mirror of
https://github.com/leozide/leocad
synced 2025-01-27 19:58:20 +01:00
Added support for flexible technic ribbed hoses.
This commit is contained in:
parent
c4689812a2
commit
1cd4a8cee0
12 changed files with 472 additions and 167 deletions
|
@ -10,6 +10,7 @@
|
|||
#include "lc_mainwindow.h"
|
||||
#include "lc_context.h"
|
||||
#include "lc_glextensions.h"
|
||||
#include "lc_synth.h"
|
||||
#include "project.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -181,6 +182,7 @@ bool lcPiecesLibrary::Load(const char* LibraryPath)
|
|||
}
|
||||
|
||||
lcLoadDefaultCategories();
|
||||
lcSynthInit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -883,7 +885,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
|||
return false;
|
||||
|
||||
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
||||
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
|
||||
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
setlocale(LC_NUMERIC, OldLocale);
|
||||
|
||||
if (!Ret)
|
||||
|
@ -904,7 +906,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
|||
return false;
|
||||
|
||||
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
||||
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
|
||||
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
setlocale(LC_NUMERIC, OldLocale);
|
||||
|
||||
if (!Ret)
|
||||
|
@ -919,7 +921,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
|
|||
return true;
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
|
||||
lcMesh* lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
|
||||
{
|
||||
lcMesh* Mesh = new lcMesh();
|
||||
|
||||
|
@ -1121,20 +1123,23 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
|
|||
}
|
||||
}
|
||||
|
||||
if (DstSection.PrimitiveType == GL_TRIANGLES)
|
||||
if (Info)
|
||||
{
|
||||
if (DstSection.ColorIndex == gDefaultColor)
|
||||
Info->mFlags |= LC_PIECE_HAS_DEFAULT;
|
||||
else
|
||||
if (DstSection.PrimitiveType == GL_TRIANGLES)
|
||||
{
|
||||
if (lcIsColorTranslucent(DstSection.ColorIndex))
|
||||
Info->mFlags |= LC_PIECE_HAS_TRANSLUCENT;
|
||||
if (DstSection.ColorIndex == gDefaultColor)
|
||||
Info->mFlags |= LC_PIECE_HAS_DEFAULT;
|
||||
else
|
||||
Info->mFlags |= LC_PIECE_HAS_SOLID;
|
||||
{
|
||||
if (lcIsColorTranslucent(DstSection.ColorIndex))
|
||||
Info->mFlags |= LC_PIECE_HAS_TRANSLUCENT;
|
||||
else
|
||||
Info->mFlags |= LC_PIECE_HAS_SOLID;
|
||||
}
|
||||
}
|
||||
else
|
||||
Info->mFlags |= LC_PIECE_HAS_LINES;
|
||||
}
|
||||
else
|
||||
Info->mFlags |= LC_PIECE_HAS_LINES;
|
||||
|
||||
NumIndices += DstSection.NumIndices;
|
||||
}
|
||||
|
@ -1190,7 +1195,11 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
|
|||
NumIndices += DstSection.NumIndices;
|
||||
}
|
||||
*/
|
||||
Info->SetMesh(Mesh);
|
||||
|
||||
if (Info)
|
||||
Info->SetMesh(Mesh);
|
||||
|
||||
return Mesh;
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::UpdateBuffers(lcContext* Context)
|
||||
|
@ -1322,12 +1331,12 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
|
||||
if (LowPrimitiveIndex == -1)
|
||||
{
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH, true))
|
||||
return false;
|
||||
|
||||
lcLibraryPrimitive* LowPrimitive = mPrimitives[LowPrimitiveIndex];
|
||||
|
@ -1337,7 +1346,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
|
||||
TextureStack.RemoveAll();
|
||||
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1358,7 +1367,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
if (!PrimFile.Open(FileName, "rt"))
|
||||
return false;
|
||||
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED))
|
||||
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1367,7 +1376,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType)
|
||||
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize)
|
||||
{
|
||||
char Buffer[1024];
|
||||
char* Line;
|
||||
|
@ -1573,7 +1582,12 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
if (Primitive->mStud)
|
||||
MeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
|
||||
else if (!Primitive->mSubFile)
|
||||
MeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
|
||||
{
|
||||
if (Optimize)
|
||||
MeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
|
||||
else
|
||||
MeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
|
||||
|
@ -1583,7 +1597,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
if (!mZipFiles[Primitive->mZipFileType]->ExtractFile(Primitive->mZipFileIndex, IncludeFile))
|
||||
continue;
|
||||
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -1602,7 +1616,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
if (!IncludeFile.Open(FileName, "rt"))
|
||||
continue;
|
||||
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1623,7 +1637,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
if (!mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, IncludeFile))
|
||||
break;
|
||||
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize))
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -1639,7 +1653,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
|
|||
if (!IncludeFile.Open(FileName, "rt"))
|
||||
break;
|
||||
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
|
||||
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType, Optimize))
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2388,6 +2402,7 @@ bool lcPiecesLibrary::LoadBuiltinPieces()
|
|||
|
||||
lcLoadDefaultColors();
|
||||
lcLoadDefaultCategories(true);
|
||||
lcSynthInit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -155,8 +155,8 @@ public:
|
|||
mNumOfficialPieces = mPieces.GetSize();
|
||||
}
|
||||
|
||||
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType);
|
||||
void CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
|
||||
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType, bool Optimize);
|
||||
lcMesh* CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
|
||||
void UpdateBuffers(lcContext* Context);
|
||||
void UnloadUnusedParts();
|
||||
|
||||
|
|
|
@ -133,10 +133,15 @@ void lcMesh::CreateBox()
|
|||
}
|
||||
|
||||
template<typename IndexType>
|
||||
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
|
||||
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance)
|
||||
{
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, NULL) || (Distance >= MinDistance))
|
||||
return false;
|
||||
|
||||
float* Verts = (float*)mVertexData;
|
||||
bool Hit = false;
|
||||
lcVector3 Intersection;
|
||||
|
||||
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
|
||||
{
|
||||
|
@ -156,7 +161,7 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
|
|||
lcVector3 v2(p2[0], p2[1], p2[2]);
|
||||
lcVector3 v3(p3[0], p3[1], p3[2]);
|
||||
|
||||
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDist, &Intersection))
|
||||
if (lcLineTriangleMinIntersection(v1, v2, v3, Start, End, &MinDistance, &Intersection))
|
||||
Hit = true;
|
||||
}
|
||||
}
|
||||
|
@ -164,12 +169,12 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
|
|||
return Hit;
|
||||
}
|
||||
|
||||
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection)
|
||||
bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist)
|
||||
{
|
||||
if (mIndexType == GL_UNSIGNED_SHORT)
|
||||
return MinIntersectDist<GLushort>(Start, End, MinDist, Intersection);
|
||||
return MinIntersectDist<GLushort>(Start, End, MinDist);
|
||||
else
|
||||
return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection);
|
||||
return MinIntersectDist<GLuint>(Start, End, MinDist);
|
||||
}
|
||||
|
||||
template<typename IndexType>
|
||||
|
|
|
@ -61,8 +61,8 @@ public:
|
|||
void ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int VertexOffset);
|
||||
|
||||
template<typename IndexType>
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist);
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist);
|
||||
|
||||
template<typename IndexType>
|
||||
bool IntersectsPlanes(const lcVector4 Planes[6]);
|
||||
|
|
|
@ -1200,7 +1200,11 @@ bool lcModel::SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVect
|
|||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
if (Piece->GetStepHide() == LC_STEP_MAX && Piece->mPieceInfo->MinIntersectDist(Piece->mModelWorld, WorldStart, WorldEnd, MinDistance))
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(Piece->mModelWorld);
|
||||
lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
|
||||
lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
|
||||
|
||||
if (Piece->GetStepHide() == LC_STEP_MAX && Piece->mPieceInfo->MinIntersectDist(Start, End, MinDistance)) // todo: this should check for piece->mMesh first
|
||||
MinIntersect = true;
|
||||
}
|
||||
|
||||
|
|
226
common/lc_synth.cpp
Normal file
226
common/lc_synth.cpp
Normal file
|
@ -0,0 +1,226 @@
|
|||
#include "lc_global.h"
|
||||
#include "lc_synth.h"
|
||||
#include "lc_library.h"
|
||||
#include "lc_application.h"
|
||||
#include "pieceinf.h"
|
||||
|
||||
void lcSynthInit()
|
||||
{
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
|
||||
struct lcRibbedHoseInfo
|
||||
{
|
||||
const char* PartID;
|
||||
float Length;
|
||||
int NumSections;
|
||||
};
|
||||
|
||||
lcRibbedHoseInfo RibbedHoseInfo[] =
|
||||
{
|
||||
{ "72504", 15.625f, 4 }, // Technic Ribbed Hose 2L
|
||||
{ "72706", 25.0f, 7 }, // Technic Ribbed Hose 3L
|
||||
{ "71952", 37.5f, 11 }, // Technic Ribbed Hose 4L
|
||||
{ "71944", 56.25f, 17 }, // Technic Ribbed Hose 6L
|
||||
{ "71951", 71.875, 22 }, // Technic Ribbed Hose 8L
|
||||
{ "71986", 106.25f, 33 }, // Technic Ribbed Hose 11L
|
||||
{ "43675", 187.5f, 58 } // Technic Ribbed Hose 19L
|
||||
};
|
||||
|
||||
lcMatrix33 RotationY = lcMatrix33RotationY(LC_PI / 2.0f);
|
||||
|
||||
for (int InfoIdx = 0; InfoIdx < sizeof(RibbedHoseInfo) / sizeof(RibbedHoseInfo[0]); InfoIdx++)
|
||||
{
|
||||
PieceInfo* Info = Library->FindPiece(RibbedHoseInfo[InfoIdx].PartID, NULL, false);
|
||||
if (Info)
|
||||
{
|
||||
lcSynthInfo* SynthInfo = new lcSynthInfo();
|
||||
|
||||
float Length = RibbedHoseInfo[InfoIdx].Length;
|
||||
SynthInfo->DefaultControlPoints[0] = lcMatrix44(RotationY, lcVector3(-Length, 0.0f, 0.0f));
|
||||
SynthInfo->DefaultControlPoints[1] = lcMatrix44(RotationY, lcVector3( Length, 0.0f, 0.0f));
|
||||
SynthInfo->DefaultStiffness = 80.0f;
|
||||
SynthInfo->NumSections = RibbedHoseInfo[InfoIdx].NumSections;
|
||||
|
||||
SynthInfo->Components[0].Transform = lcMatrix44Identity();
|
||||
SynthInfo->Components[0].Transform[1][1] = -1.0f;
|
||||
strcpy(SynthInfo->Components[0].PartID, "79.DAT");
|
||||
SynthInfo->Components[0].Length = 6.25f;
|
||||
SynthInfo->Components[1].Transform = lcMatrix44Identity();
|
||||
strcpy(SynthInfo->Components[1].PartID, "80.DAT");
|
||||
SynthInfo->Components[1].Length = 6.25f;
|
||||
SynthInfo->Components[2].Transform = lcMatrix44Identity();
|
||||
strcpy(SynthInfo->Components[2].PartID, "79.DAT");
|
||||
SynthInfo->Components[2].Length = 6.25f;
|
||||
Info->SetSynthInfo(SynthInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline lcMatrix44 lcMatrix44LeoCADToLDraw(const lcMatrix44& Matrix)
|
||||
{
|
||||
lcMatrix44 m;
|
||||
|
||||
m.r[0] = lcVector4( Matrix[0][0], -Matrix[2][0], Matrix[1][0], 0.0f);
|
||||
m.r[1] = lcVector4(-Matrix[0][2], Matrix[2][2], -Matrix[1][2], 0.0f);
|
||||
m.r[2] = lcVector4( Matrix[0][1], -Matrix[2][1], Matrix[1][1], 0.0f);
|
||||
m.r[3] = lcVector4( Matrix[3][0], -Matrix[3][2], Matrix[3][1], 1.0f);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
#include "lc_file.h"
|
||||
|
||||
lcMesh* lcSynthCreateMesh(lcSynthInfo* SynthInfo, const lcArray<lcPieceControlPoint>& ControlPoints)
|
||||
{
|
||||
lcArray<lcMatrix44> Sections;
|
||||
float SectionLength = 0.0f;
|
||||
|
||||
for (int ControlPointIdx = 0; ControlPointIdx < ControlPoints.GetSize() - 1; ControlPointIdx++)
|
||||
{
|
||||
lcVector3 SegmentControlPoints[4];
|
||||
|
||||
lcMatrix44 StartTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx].Transform);
|
||||
lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPointIdx + 1].Transform);
|
||||
|
||||
if (ControlPointIdx == 0)
|
||||
{
|
||||
StartTransform = lcMul(StartTransform, SynthInfo->Components[0].Transform);
|
||||
Sections.Add(StartTransform);
|
||||
SectionLength = SynthInfo->Components[0].Length;
|
||||
}
|
||||
|
||||
if (ControlPointIdx == ControlPoints.GetSize() - 2)
|
||||
EndTransform = lcMul(EndTransform, lcMatrix44(lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
SegmentControlPoints[0] = StartTransform.GetTranslation();
|
||||
SegmentControlPoints[1] = lcMul31(lcVector3(0.0f, ControlPoints[ControlPointIdx].Stiffness, 0.0f), StartTransform);
|
||||
SegmentControlPoints[2] = lcMul31(lcVector3(0.0f, -ControlPoints[ControlPointIdx + 1].Stiffness, 0.0f), EndTransform);
|
||||
SegmentControlPoints[3] = EndTransform.GetTranslation();
|
||||
|
||||
float PointDistance = lcLength(SegmentControlPoints[3] - SegmentControlPoints[0]);
|
||||
float PointDot = lcDot(SegmentControlPoints[1], SegmentControlPoints[2]);
|
||||
|
||||
if ((PointDistance < ControlPoints[ControlPointIdx].Stiffness + ControlPoints[ControlPointIdx + 1].Stiffness) && (PointDot <= 0.001f))
|
||||
{
|
||||
float Scale = 1.0f / (ControlPoints[ControlPointIdx].Stiffness + ControlPoints[ControlPointIdx + 1].Stiffness);
|
||||
|
||||
SegmentControlPoints[1] = lcMul31(lcVector3(0.0f, ControlPoints[ControlPointIdx].Stiffness * Scale, 0.0f), StartTransform);
|
||||
SegmentControlPoints[2] = lcMul31(lcVector3(0.0f, -ControlPoints[ControlPointIdx + 1].Stiffness * Scale, 0.0f), EndTransform);
|
||||
}
|
||||
|
||||
const int NumCurvePoints = 8192;
|
||||
lcArray<lcVector3> CurvePoints;
|
||||
CurvePoints.AllocGrow(NumCurvePoints);
|
||||
|
||||
for (int PointIdx = 0; PointIdx < NumCurvePoints; PointIdx++)
|
||||
{
|
||||
float t = (float)PointIdx / (float)(NumCurvePoints - 1);
|
||||
float it = 1.0f - t;
|
||||
|
||||
lcVector3 Position = it * it * it * SegmentControlPoints[0] + it * it * 3.0f * t * SegmentControlPoints[1] + it * 3.0 * t * t * SegmentControlPoints[2] + t * t * t * SegmentControlPoints[3];
|
||||
CurvePoints.Add(Position);
|
||||
}
|
||||
|
||||
int CurrentPointIndex = 0;
|
||||
|
||||
lcVector3 StartUp(lcMul30(lcVector3(1.0f, 0.0f, 0.0f), StartTransform));
|
||||
lcVector3 EndUp(lcMul30(lcVector3(1.0f, 0.0f, 0.0f), EndTransform));
|
||||
lcVector4 UpRotation;
|
||||
float UpDot = lcDot(StartUp, EndUp);
|
||||
|
||||
if (UpDot < 0.99f)
|
||||
UpRotation = lcVector4(lcCross(StartUp, EndUp), acosf(UpDot));
|
||||
else
|
||||
UpRotation = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
float CurrentSegmentLength = 0.0f;
|
||||
float TotalSegmentLength = 0.0f;
|
||||
|
||||
for (int PointIdx = 0; PointIdx < CurvePoints.GetSize() - 1; PointIdx++)
|
||||
TotalSegmentLength += lcLength(CurvePoints[CurrentPointIndex] - CurvePoints[CurrentPointIndex + 1]);
|
||||
|
||||
while (CurrentPointIndex < CurvePoints.GetSize() - 1)
|
||||
{
|
||||
float Length = lcLength(CurvePoints[CurrentPointIndex] - CurvePoints[CurrentPointIndex + 1]);
|
||||
CurrentSegmentLength += Length;
|
||||
SectionLength -= Length;
|
||||
CurrentPointIndex++;
|
||||
|
||||
if (SectionLength > 0.0f)
|
||||
continue;
|
||||
|
||||
float t = (float)CurrentPointIndex / (float)(NumCurvePoints - 1);
|
||||
float it = 1.0f - t;
|
||||
|
||||
lcVector3 Tangent = -3.0f * it * it * SegmentControlPoints[0] + (3.0f * it * it - 6.0f * t * it) * SegmentControlPoints[1] + (-3.0f * t * t + 6.0f * t * it) * SegmentControlPoints[2] + 3.0f * t * t * SegmentControlPoints[3];
|
||||
lcVector3 Up = lcMul(StartUp, lcMatrix33FromAxisAngle(lcVector3(UpRotation[0], UpRotation[1], UpRotation[2]), UpRotation[3] * (CurrentSegmentLength / TotalSegmentLength)));
|
||||
lcVector3 Side = lcCross(Tangent, Up);
|
||||
Up = lcCross(Side, Tangent);
|
||||
|
||||
Sections.Add(lcMatrix44(lcMatrix33(lcNormalize(Up), lcNormalize(Tangent), lcNormalize(Side)), CurvePoints[CurrentPointIndex]));
|
||||
|
||||
if (Sections.GetSize() == SynthInfo->NumSections + 2)
|
||||
break;
|
||||
|
||||
if (Sections.GetSize() < SynthInfo->NumSections + 1)
|
||||
SectionLength += SynthInfo->Components[1].Length;
|
||||
else
|
||||
SectionLength += SynthInfo->Components[2].Length;
|
||||
}
|
||||
}
|
||||
|
||||
while (Sections.GetSize() < SynthInfo->NumSections + 2)
|
||||
{
|
||||
lcMatrix44 EndTransform = lcMatrix44LeoCADToLDraw(ControlPoints[ControlPoints.GetSize() - 1].Transform);
|
||||
EndTransform = lcMul(EndTransform, lcMatrix44(lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
lcVector3 Position = lcMul31(lcVector3(0.0f, SectionLength, 0.0f), EndTransform);
|
||||
EndTransform.SetTranslation(Position);
|
||||
Sections.Add(EndTransform);
|
||||
|
||||
if (Sections.GetSize() < SynthInfo->NumSections + 1)
|
||||
SectionLength += SynthInfo->Components[1].Length;
|
||||
else
|
||||
SectionLength += SynthInfo->Components[2].Length;
|
||||
}
|
||||
|
||||
// todo: rewrite this to pass the parts directly
|
||||
|
||||
lcMemFile f;
|
||||
|
||||
for (int i = 0; i < Sections.GetSize(); i++)
|
||||
{
|
||||
char str[256];
|
||||
|
||||
const lcMatrix44& Transform = Sections[i];
|
||||
const char* Name;
|
||||
if (i == 0)
|
||||
Name = SynthInfo->Components[0].PartID;
|
||||
else if (i == Sections.GetSize() - 1)
|
||||
Name = SynthInfo->Components[2].PartID;
|
||||
else
|
||||
Name = SynthInfo->Components[1].PartID;
|
||||
|
||||
sprintf(str, "1 16 %f %f %f %f %f %f %f %f %f %f %f %f %s\n", Transform[3][0], Transform[3][1], Transform[3][2],
|
||||
Transform[0][0], Transform[1][0], Transform[2][0],
|
||||
Transform[0][1], Transform[1][1], Transform[2][1],
|
||||
Transform[0][2], Transform[1][2], Transform[2][2],
|
||||
Name);
|
||||
|
||||
f.WriteBuffer(str, strlen(str));
|
||||
}
|
||||
|
||||
f.WriteU8(0);
|
||||
|
||||
lcLibraryMeshData MeshData;
|
||||
lcArray<lcLibraryTextureMap> TextureStack;
|
||||
f.Seek(0, SEEK_SET);
|
||||
|
||||
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
||||
bool Ret = lcGetPiecesLibrary()->ReadMeshData(f, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, false);
|
||||
setlocale(LC_NUMERIC, OldLocale);
|
||||
|
||||
if (Ret)
|
||||
return lcGetPiecesLibrary()->CreateMesh(NULL, MeshData);
|
||||
|
||||
return NULL;
|
||||
}
|
26
common/lc_synth.h
Normal file
26
common/lc_synth.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _LC_SYNTH_H_
|
||||
#define _LC_SYNTH_H_
|
||||
|
||||
#include "lc_math.h"
|
||||
#include "piece.h"
|
||||
#include "pieceinf.h"
|
||||
|
||||
struct lcSynthComponent
|
||||
{
|
||||
char PartID[LC_PIECE_NAME_LEN];
|
||||
lcMatrix44 Transform;
|
||||
float Length;
|
||||
};
|
||||
|
||||
struct lcSynthInfo
|
||||
{
|
||||
lcMatrix44 DefaultControlPoints[2];
|
||||
lcSynthComponent Components[3];
|
||||
float DefaultStiffness;
|
||||
int NumSections;
|
||||
};
|
||||
|
||||
void lcSynthInit();
|
||||
lcMesh* lcSynthCreateMesh(lcSynthInfo* SynthInfo, const lcArray<lcPieceControlPoint>& ControlPoints);
|
||||
|
||||
#endif // _LC_SYNTH_H_
|
197
common/piece.cpp
197
common/piece.cpp
|
@ -15,6 +15,7 @@
|
|||
#include "lc_library.h"
|
||||
#include "lc_context.h"
|
||||
#include "lc_qutils.h"
|
||||
#include "lc_synth.h"
|
||||
|
||||
#define LC_PIECE_CONTROL_POINT_SIZE 10.0f
|
||||
|
||||
|
@ -50,19 +51,21 @@ void lcPiece::SetPieceInfo(PieceInfo* Info)
|
|||
if (mPieceInfo)
|
||||
mPieceInfo->AddRef();
|
||||
|
||||
if (0) // todo: get control points from the piece info
|
||||
mControlPoints.RemoveAll();
|
||||
delete mMesh;
|
||||
mMesh = NULL;
|
||||
|
||||
lcSynthInfo* SynthInfo = mPieceInfo ? mPieceInfo->GetSynthInfo() : NULL;
|
||||
|
||||
if (SynthInfo)
|
||||
{
|
||||
mControlPoints.SetSize(2);
|
||||
mControlPoints[0].Position = lcVector3(0, 0, -30);
|
||||
mControlPoints[1].Position = lcVector3(0, 0, 30);
|
||||
mControlPoints[0].Transform = SynthInfo->DefaultControlPoints[0];
|
||||
mControlPoints[0].Stiffness = SynthInfo->DefaultStiffness;
|
||||
mControlPoints[1].Transform = SynthInfo->DefaultControlPoints[1];
|
||||
mControlPoints[1].Stiffness = SynthInfo->DefaultStiffness;
|
||||
UpdateMesh();
|
||||
}
|
||||
else
|
||||
{
|
||||
mControlPoints.RemoveAll();
|
||||
delete mMesh;
|
||||
mMesh = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void lcPiece::SaveLDraw(QTextStream& Stream) const
|
||||
|
@ -428,7 +431,19 @@ void lcPiece::RemoveTime(lcStep Start, lcStep Time)
|
|||
|
||||
void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
|
||||
{
|
||||
if (mPieceInfo->MinIntersectDist(mModelWorld, ObjectRayTest.Start, ObjectRayTest.End, ObjectRayTest.Distance))
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld);
|
||||
lcVector3 Start = lcMul31(ObjectRayTest.Start, InverseWorldMatrix);
|
||||
lcVector3 End = lcMul31(ObjectRayTest.End, InverseWorldMatrix);
|
||||
|
||||
if (mMesh)
|
||||
{
|
||||
if (mMesh->MinIntersectDist(Start, End, ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION;
|
||||
}
|
||||
}
|
||||
else if (mPieceInfo->MinIntersectDist(Start, End, ObjectRayTest.Distance))
|
||||
{
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
|
||||
ObjectRayTest.ObjectSection.Section = LC_PIECE_SECTION_POSITION;
|
||||
|
@ -436,20 +451,17 @@ void lcPiece::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|||
|
||||
if (AreControlPointsVisible())
|
||||
{
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(mModelWorld);
|
||||
lcVector3 Start = lcMul31(ObjectRayTest.Start, InverseWorldMatrix);
|
||||
lcVector3 End = lcMul31(ObjectRayTest.End, InverseWorldMatrix);
|
||||
lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE);
|
||||
lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE);
|
||||
|
||||
for (int ControlPointIdx = 0; ControlPointIdx < mControlPoints.GetSize(); ControlPointIdx++)
|
||||
{
|
||||
lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE);
|
||||
lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE);
|
||||
|
||||
Min += mControlPoints[ControlPointIdx].Position;
|
||||
Max += mControlPoints[ControlPointIdx].Position;
|
||||
lcMatrix44 InverseTransform = lcMatrix44AffineInverse(mControlPoints[ControlPointIdx].Transform);
|
||||
lcVector3 PointStart = lcMul31(Start, InverseTransform);
|
||||
lcVector3 PointEnd = lcMul31(End, InverseTransform);
|
||||
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) || (Distance >= ObjectRayTest.Distance))
|
||||
if (!lcBoundingBoxRayIntersectDistance(Min, Max, PointStart, PointEnd, &Distance, NULL) || (Distance >= ObjectRayTest.Distance))
|
||||
continue;
|
||||
|
||||
ObjectRayTest.ObjectSection.Object = const_cast<lcPiece*>(this);
|
||||
|
@ -548,31 +560,30 @@ void lcPiece::DrawInterface(lcContext* Context) const
|
|||
|
||||
if (AreControlPointsVisible())
|
||||
{
|
||||
float Verts[8 * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE);
|
||||
lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE);
|
||||
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
|
||||
const GLushort Indices[36] =
|
||||
{
|
||||
0, 1, 2, 0, 2, 3, 7, 6, 5, 7, 5, 4, 0, 1, 5, 0, 5, 4,
|
||||
2, 3, 7, 2, 7, 6, 0, 3, 7, 0, 7, 4, 1, 2, 6, 1, 6, 5
|
||||
};
|
||||
|
||||
for (int ControlPointIdx = 0; ControlPointIdx < mControlPoints.GetSize(); ControlPointIdx++)
|
||||
{
|
||||
float Verts[8 * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
lcVector3 Min(-LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE, -LC_PIECE_CONTROL_POINT_SIZE);
|
||||
lcVector3 Max(LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE, LC_PIECE_CONTROL_POINT_SIZE);
|
||||
|
||||
Min += mControlPoints[ControlPointIdx].Position;
|
||||
Max += mControlPoints[ControlPointIdx].Position;
|
||||
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
|
||||
const GLushort Indices[36] =
|
||||
{
|
||||
0, 1, 2, 0, 2, 3, 7, 6, 5, 7, 5, 4, 0, 1, 5, 0, 5, 4,
|
||||
2, 3, 7, 2, 7, 6, 0, 3, 7, 0, 7, 4, 1, 2, 6, 1, 6, 5
|
||||
};
|
||||
Context->SetWorldMatrix(lcMul(mControlPoints[ControlPointIdx].Transform, mModelWorld));
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormat(0, 3, 0, 0);
|
||||
|
@ -616,13 +627,13 @@ void lcPiece::AddRenderMeshes(lcScene& Scene, bool DrawInterface) const
|
|||
RenderMesh.Distance = fabsf(lcMul31(mModelWorld[3], Scene.mViewMatrix).z);
|
||||
RenderMesh.LodIndex = RenderMesh.Mesh->GetLodIndex(RenderMesh.Distance);
|
||||
|
||||
// bool Translucent = lcIsColorTranslucent(mColorIndex);
|
||||
bool Translucent = lcIsColorTranslucent(mColorIndex);
|
||||
|
||||
// if ((mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent))
|
||||
if ((mPieceInfo->mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mPieceInfo->mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent))
|
||||
Scene.mOpaqueMeshes.Add(RenderMesh);
|
||||
|
||||
// if ((mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
|
||||
// Scene.mTranslucentMeshes.Add(RenderMesh);
|
||||
if ((mPieceInfo->mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mPieceInfo->mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
|
||||
Scene.mTranslucentMeshes.Add(RenderMesh);
|
||||
}
|
||||
|
||||
if (Selected)
|
||||
|
@ -646,7 +657,12 @@ void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance)
|
|||
int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1;
|
||||
|
||||
if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize())
|
||||
mControlPoints[ControlPointIndex].Position += Distance;
|
||||
{
|
||||
lcMatrix33 InverseWorldMatrix = lcMatrix33AffineInverse(lcMatrix33(mModelWorld));
|
||||
lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform;
|
||||
|
||||
Transform.SetTranslation(Transform.GetTranslation() + lcMul(Distance, InverseWorldMatrix));
|
||||
}
|
||||
|
||||
UpdateMesh();
|
||||
}
|
||||
|
@ -654,21 +670,45 @@ void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance)
|
|||
|
||||
void lcPiece::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame)
|
||||
{
|
||||
lcVector3 Distance = mModelWorld.GetTranslation() - Center;
|
||||
lcMatrix33 LocalToWorldMatrix = lcMatrix33(mModelWorld);
|
||||
lcuint32 Section = GetFocusSection();
|
||||
|
||||
lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame);
|
||||
lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix);
|
||||
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
||||
{
|
||||
lcVector3 Distance = mModelWorld.GetTranslation() - Center;
|
||||
lcMatrix33 LocalToWorldMatrix = lcMatrix33(mModelWorld);
|
||||
|
||||
lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix);
|
||||
lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame);
|
||||
lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix);
|
||||
|
||||
Distance = lcMul(Distance, WorldToLocalMatrix);
|
||||
Distance = lcMul(Distance, NewLocalToWorldMatrix);
|
||||
lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix);
|
||||
|
||||
NewLocalToWorldMatrix.Orthonormalize();
|
||||
Distance = lcMul(Distance, WorldToLocalMatrix);
|
||||
Distance = lcMul(Distance, NewLocalToWorldMatrix);
|
||||
|
||||
SetPosition(Center + Distance, Step, AddKey);
|
||||
SetRotation(NewLocalToWorldMatrix, Step, AddKey);
|
||||
NewLocalToWorldMatrix.Orthonormalize();
|
||||
|
||||
SetPosition(Center + Distance, Step, AddKey);
|
||||
SetRotation(NewLocalToWorldMatrix, Step, AddKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1;
|
||||
|
||||
if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize())
|
||||
{
|
||||
lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform;
|
||||
lcMatrix33 PieceWorldMatrix(mModelWorld);
|
||||
lcMatrix33 LocalToWorldMatrix = lcMul(lcMatrix33(Transform), PieceWorldMatrix);
|
||||
|
||||
lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame);
|
||||
lcMatrix33 NewLocalToWorldMatrix = lcMul(lcMul(LocalToFocusMatrix, RotationMatrix), lcMatrix33AffineInverse(PieceWorldMatrix));
|
||||
|
||||
NewLocalToWorldMatrix.Orthonormalize();
|
||||
Transform = lcMatrix44(NewLocalToWorldMatrix, Transform.GetTranslation());
|
||||
}
|
||||
|
||||
UpdateMesh();
|
||||
}
|
||||
}
|
||||
|
||||
void lcPiece::MovePivotPoint(const lcVector3& Distance)
|
||||
|
@ -747,46 +787,5 @@ void lcPiece::UpdatePosition(lcStep Step)
|
|||
void lcPiece::UpdateMesh()
|
||||
{
|
||||
delete mMesh;
|
||||
|
||||
lcuint16 NumSections[LC_NUM_MESH_LODS] = { 1, 1 };
|
||||
|
||||
mMesh = new lcMesh();
|
||||
mMesh->Create(NumSections, 2, 0, 2);
|
||||
|
||||
NumSections[0] = 2;
|
||||
NumSections[1] = 2;
|
||||
|
||||
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
|
||||
{
|
||||
lcMeshSection& Section = mMesh->mLods[LodIdx].Sections[0];
|
||||
|
||||
Section.ColorIndex = gDefaultColor;
|
||||
Section.PrimitiveType = GL_LINES;
|
||||
Section.NumIndices = 2;
|
||||
Section.Texture = NULL;
|
||||
Section.IndexOffset = 0;
|
||||
}
|
||||
|
||||
lcuint16* Index = (lcuint16*)mMesh->mIndexData;
|
||||
*Index++ = 0;
|
||||
*Index++ = 1;
|
||||
|
||||
lcVertex* Verts = (lcVertex*)mMesh->mVertexData;
|
||||
Verts[0].Position = mControlPoints[0].Position;
|
||||
Verts[1].Position = mControlPoints[1].Position;
|
||||
|
||||
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
|
||||
Min = lcMin(mControlPoints[0].Position, Min);
|
||||
Min = lcMin(mControlPoints[1].Position, Min);
|
||||
|
||||
Max = lcMax(mControlPoints[0].Position, Max);
|
||||
Max = lcMax(mControlPoints[1].Position, Max);
|
||||
|
||||
Min -= lcVector3(5.0f, 5.0f, 5.0f);
|
||||
Max += lcVector3(5.0f, 5.0f, 5.0f);
|
||||
|
||||
mMesh->mRadius = lcLength(Max - Min) / 2.0f;
|
||||
mMesh->mBoundingBox.Min = Min;
|
||||
mMesh->mBoundingBox.Max = Max;
|
||||
mMesh = lcSynthCreateMesh(mPieceInfo->GetSynthInfo(), mControlPoints);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ enum lcPieceSection
|
|||
|
||||
struct lcPieceControlPoint
|
||||
{
|
||||
lcVector3 Position;
|
||||
lcMatrix44 Transform;
|
||||
float Stiffness;
|
||||
};
|
||||
|
||||
class lcPiece : public lcObject
|
||||
|
@ -298,28 +299,28 @@ public:
|
|||
return mModelWorld.GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_1:
|
||||
return lcMul31(mControlPoints[0].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[0].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_2:
|
||||
return lcMul31(mControlPoints[1].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[1].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_3:
|
||||
return lcMul31(mControlPoints[2].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[2].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_4:
|
||||
return lcMul31(mControlPoints[3].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[3].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_5:
|
||||
return lcMul31(mControlPoints[4].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[4].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_6:
|
||||
return lcMul31(mControlPoints[5].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[5].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_7:
|
||||
return lcMul31(mControlPoints[6].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[6].Transform, mModelWorld).GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_8:
|
||||
return lcMul31(mControlPoints[7].Position, mModelWorld);
|
||||
return lcMul(mControlPoints[7].Transform, mModelWorld).GetTranslation();
|
||||
}
|
||||
|
||||
return lcVector3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -451,10 +452,27 @@ public:
|
|||
|
||||
lcMatrix33 GetRelativeRotation() const
|
||||
{
|
||||
if (mState & LC_PIECE_PIVOT_POINT_VALID)
|
||||
return lcMatrix33(lcMul(mModelWorld, mPivotMatrix));
|
||||
lcuint32 Section = GetFocusSection();
|
||||
|
||||
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
||||
{
|
||||
if (mState & LC_PIECE_PIVOT_POINT_VALID)
|
||||
return lcMatrix33(lcMul(mModelWorld, mPivotMatrix));
|
||||
else
|
||||
return lcMatrix33(mModelWorld);
|
||||
}
|
||||
else
|
||||
return lcMatrix33(mModelWorld);
|
||||
{
|
||||
int ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_1;
|
||||
|
||||
if (ControlPointIndex >= 0 && ControlPointIndex < mControlPoints.GetSize())
|
||||
{
|
||||
lcMatrix44& Transform = mControlPoints[ControlPointIndex].Transform;
|
||||
return lcMatrix33(lcMul(Transform, mModelWorld));
|
||||
}
|
||||
|
||||
return lcMatrix33Identity();
|
||||
}
|
||||
}
|
||||
|
||||
void ResetPivotPoint()
|
||||
|
@ -494,7 +512,7 @@ protected:
|
|||
lcStep mStepShow;
|
||||
lcStep mStepHide;
|
||||
|
||||
lcuint8 mState;
|
||||
lcuint32 mState;
|
||||
lcArray<lcPieceControlPoint> mControlPoints;
|
||||
lcMesh* mMesh;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "lc_application.h"
|
||||
#include "lc_model.h"
|
||||
#include "lc_context.h"
|
||||
#include "lc_synth.h"
|
||||
#include "camera.h"
|
||||
#include <locale.h>
|
||||
|
||||
|
@ -20,12 +21,15 @@ PieceInfo::PieceInfo()
|
|||
mRefCount = 0;
|
||||
mMesh = NULL;
|
||||
mModel = NULL;
|
||||
mSynthInfo = NULL;
|
||||
}
|
||||
|
||||
PieceInfo::~PieceInfo()
|
||||
{
|
||||
if (mLoaded)
|
||||
Unload();
|
||||
|
||||
delete mSynthInfo;
|
||||
}
|
||||
|
||||
QString PieceInfo::GetSaveID() const
|
||||
|
@ -79,7 +83,7 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
|
|||
PieceFile.Seek(0, SEEK_SET);
|
||||
|
||||
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
||||
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
|
||||
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED, true);
|
||||
setlocale(LC_NUMERIC, OldLocale);
|
||||
|
||||
if (Ret)
|
||||
|
@ -154,32 +158,25 @@ void PieceInfo::Unload()
|
|||
lcGetPiecesLibrary()->RemovePiece(this);
|
||||
}
|
||||
|
||||
bool PieceInfo::MinIntersectDist(const lcMatrix44& WorldMatrix, const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const
|
||||
bool PieceInfo::MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const
|
||||
{
|
||||
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix);
|
||||
lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
|
||||
lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
|
||||
|
||||
const lcVector3& Min = mBoundingBox.Min;
|
||||
const lcVector3& Max = mBoundingBox.Max;
|
||||
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) || (Distance >= MinDistance))
|
||||
return false;
|
||||
|
||||
if (mFlags & LC_PIECE_PLACEHOLDER)
|
||||
return true;
|
||||
|
||||
bool Intersect = false;
|
||||
|
||||
if (mMesh)
|
||||
if (mFlags & (LC_PIECE_PLACEHOLDER | LC_PIECE_MODEL))
|
||||
{
|
||||
lcVector3 Intersection;
|
||||
Intersect = mMesh->MinIntersectDist(Start, End, MinDistance, Intersection);
|
||||
float Distance;
|
||||
if (!lcBoundingBoxRayIntersectDistance(mBoundingBox.Min, mBoundingBox.Max, Start, End, &Distance, NULL) || (Distance >= MinDistance))
|
||||
return false;
|
||||
|
||||
if (mFlags & LC_PIECE_PLACEHOLDER)
|
||||
return true;
|
||||
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance);
|
||||
}
|
||||
|
||||
if (mFlags & LC_PIECE_MODEL)
|
||||
Intersect |= mModel->SubModelMinIntersectDist(Start, End, MinDistance);
|
||||
if (mMesh)
|
||||
Intersect = mMesh->MinIntersectDist(Start, End, MinDistance);
|
||||
|
||||
return Intersect;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#define LC_PIECE_NAME_LEN 256
|
||||
|
||||
struct lcSynthInfo;
|
||||
|
||||
class PieceInfo
|
||||
{
|
||||
public:
|
||||
|
@ -34,6 +36,16 @@ public:
|
|||
mBoundingBox.Max = Max;
|
||||
}
|
||||
|
||||
lcSynthInfo* GetSynthInfo() const
|
||||
{
|
||||
return mSynthInfo;
|
||||
}
|
||||
|
||||
void SetSynthInfo(lcSynthInfo* SynthInfo)
|
||||
{
|
||||
mSynthInfo = SynthInfo;
|
||||
}
|
||||
|
||||
lcMesh* GetMesh() const
|
||||
{
|
||||
return mMesh;
|
||||
|
@ -129,7 +141,7 @@ public:
|
|||
void SetPlaceholder();
|
||||
void SetModel(lcModel* Model, bool UpdateMesh);
|
||||
bool IncludesModel(const lcModel* Model) const;
|
||||
bool MinIntersectDist(const lcMatrix44& WorldMatrix, const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const;
|
||||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDistance) const;
|
||||
bool BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 Planes[6]) const;
|
||||
void GetPartsList(int DefaultColorIndex, lcArray<lcPartsListEntry>& PartsList) const;
|
||||
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcArray<lcModelPartsEntry>& ModelParts) const;
|
||||
|
@ -149,6 +161,7 @@ protected:
|
|||
lcModel* mModel;
|
||||
lcMesh* mMesh;
|
||||
lcBoundingBox mBoundingBox;
|
||||
lcSynthInfo* mSynthInfo;
|
||||
|
||||
void Load();
|
||||
void Unload();
|
||||
|
|
|
@ -143,6 +143,7 @@ SOURCES += common/view.cpp \
|
|||
common/lc_model.cpp \
|
||||
common/lc_profile.cpp \
|
||||
common/lc_shortcuts.cpp \
|
||||
common/lc_synth.cpp \
|
||||
common/lc_texture.cpp \
|
||||
common/lc_zipfile.cpp \
|
||||
common/image.cpp \
|
||||
|
@ -205,6 +206,7 @@ HEADERS += \
|
|||
common/lc_model.h \
|
||||
common/lc_profile.h \
|
||||
common/lc_shortcuts.h \
|
||||
common/lc_synth.h \
|
||||
common/lc_texture.h \
|
||||
common/lc_zipfile.h \
|
||||
common/image.h \
|
||||
|
|
Loading…
Add table
Reference in a new issue