2012-03-20 01:57:42 +01:00
|
|
|
#include "lc_global.h"
|
2012-03-29 03:10:55 +02:00
|
|
|
#include "lc_math.h"
|
2012-04-14 01:41:58 +02:00
|
|
|
#include "lc_mesh.h"
|
|
|
|
#include "lc_colors.h"
|
2012-10-12 01:55:55 +02:00
|
|
|
#include "lc_texture.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "opengl.h"
|
|
|
|
#include "pieceinf.h"
|
2012-10-02 03:23:44 +02:00
|
|
|
#include "lc_library.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "lc_application.h"
|
2014-12-24 16:52:52 +01:00
|
|
|
#include "lc_model.h"
|
|
|
|
#include "lc_context.h"
|
|
|
|
#include "camera.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-08 00:58:59 +02:00
|
|
|
PieceInfo::PieceInfo()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-08 00:58:59 +02:00
|
|
|
mZipFileType = LC_NUM_ZIPFILES;
|
|
|
|
mZipFileIndex = -1;
|
2012-10-03 00:16:36 +02:00
|
|
|
mFlags = 0;
|
2012-10-12 01:55:55 +02:00
|
|
|
mRefCount = 0;
|
2015-01-08 05:50:38 +01:00
|
|
|
mMesh = NULL;
|
2014-12-24 16:52:52 +01:00
|
|
|
mModel = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-04-14 01:41:58 +02:00
|
|
|
PieceInfo::~PieceInfo()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-10-12 02:21:04 +02:00
|
|
|
if (mRefCount)
|
|
|
|
Unload();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-12-26 18:09:11 +01:00
|
|
|
QString PieceInfo::GetSaveID() const
|
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
2015-01-07 17:52:42 +01:00
|
|
|
return QString::fromLatin1(m_strName);
|
2014-12-26 18:09:11 +01:00
|
|
|
|
|
|
|
return QString::fromLatin1(m_strName) + QLatin1String(".DAT");
|
|
|
|
}
|
|
|
|
|
2015-01-08 05:50:38 +01:00
|
|
|
void PieceInfo::SetPlaceholder()
|
|
|
|
{
|
|
|
|
m_fDimensions[0] = 10.0f;
|
|
|
|
m_fDimensions[1] = 10.0f;
|
|
|
|
m_fDimensions[2] = 4.0f;
|
|
|
|
m_fDimensions[3] = -10.0f;
|
|
|
|
m_fDimensions[4] = -10.0f;
|
|
|
|
m_fDimensions[5] = -24.0f;
|
|
|
|
|
|
|
|
mFlags = LC_PIECE_PLACEHOLDER | LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
|
|
|
|
mModel = NULL;
|
|
|
|
|
|
|
|
delete mMesh;
|
|
|
|
mMesh = NULL;
|
|
|
|
}
|
|
|
|
|
2014-12-24 16:52:52 +01:00
|
|
|
void PieceInfo::SetModel(lcModel* Model)
|
|
|
|
{
|
|
|
|
mFlags = LC_PIECE_MODEL;
|
|
|
|
mModel = Model;
|
|
|
|
|
2015-02-09 02:33:28 +01:00
|
|
|
strncpy(m_strName, Model->GetProperties().mName.toUpper().toLatin1().data(), sizeof(m_strName));
|
2015-01-17 19:29:10 +01:00
|
|
|
m_strName[sizeof(m_strName)-1] = 0;
|
|
|
|
strncpy(m_strDescription, Model->GetProperties().mName.toLatin1().data(), sizeof(m_strDescription));
|
|
|
|
m_strDescription[sizeof(m_strDescription)-1] = 0;
|
|
|
|
|
2014-12-24 16:52:52 +01:00
|
|
|
delete mMesh;
|
|
|
|
mMesh = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PieceInfo::IncludesModel(const lcModel* Model) const
|
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
{
|
|
|
|
if (mModel == Model)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return mModel->IncludesModel(Model);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-02-05 06:03:59 +01:00
|
|
|
void PieceInfo::CreatePlaceholder(const char* Name)
|
|
|
|
{
|
|
|
|
strncpy(m_strName, Name, sizeof(m_strName));
|
|
|
|
m_strName[sizeof(m_strName)-1] = 0;
|
|
|
|
strncpy(m_strDescription, Name, sizeof(m_strDescription));
|
|
|
|
m_strDescription[sizeof(m_strDescription)-1] = 0;
|
|
|
|
|
2015-01-08 05:50:38 +01:00
|
|
|
SetPlaceholder();
|
2012-02-05 06:03:59 +01:00
|
|
|
}
|
|
|
|
|
2012-10-12 01:55:55 +02:00
|
|
|
void PieceInfo::Load()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2015-01-07 17:52:42 +01:00
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
return;
|
|
|
|
else if (mFlags & LC_PIECE_PLACEHOLDER)
|
2012-10-03 00:16:36 +02:00
|
|
|
mFlags |= LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES;
|
2012-10-02 03:23:44 +02:00
|
|
|
else
|
2012-10-03 00:16:36 +02:00
|
|
|
lcGetPiecesLibrary()->LoadPiece(this);
|
2014-09-11 21:55:34 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-10-12 01:55:55 +02:00
|
|
|
void PieceInfo::Unload()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-12-24 16:52:52 +01:00
|
|
|
if (mMesh)
|
2012-10-12 01:55:55 +02:00
|
|
|
{
|
2014-12-24 16:52:52 +01:00
|
|
|
for (int SectionIdx = 0; SectionIdx < mMesh->mNumSections; SectionIdx++)
|
|
|
|
{
|
|
|
|
lcMeshSection& Section = mMesh->mSections[SectionIdx];
|
2012-10-12 01:55:55 +02:00
|
|
|
|
2014-12-24 16:52:52 +01:00
|
|
|
if (Section.Texture)
|
|
|
|
Section.Texture->Release();
|
|
|
|
}
|
2012-10-12 01:55:55 +02:00
|
|
|
|
2014-12-24 16:52:52 +01:00
|
|
|
delete mMesh;
|
|
|
|
mMesh = NULL;
|
|
|
|
}
|
2015-01-07 17:52:42 +01:00
|
|
|
|
|
|
|
mModel = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-12-26 16:44:46 +01:00
|
|
|
bool PieceInfo::MinIntersectDist(const lcMatrix44& WorldMatrix, const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const
|
|
|
|
{
|
|
|
|
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix);
|
|
|
|
lcVector3 Start = lcMul31(WorldStart, InverseWorldMatrix);
|
|
|
|
lcVector3 End = lcMul31(WorldEnd, InverseWorldMatrix);
|
|
|
|
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
return mModel->SubModelMinIntersectDist(Start, End, MinDistance);
|
|
|
|
|
|
|
|
lcVector3 Min(m_fDimensions[3], m_fDimensions[4], m_fDimensions[5]);
|
|
|
|
lcVector3 Max(m_fDimensions[0], m_fDimensions[1], m_fDimensions[2]);
|
|
|
|
|
|
|
|
float Distance;
|
|
|
|
if (!lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) || (Distance >= MinDistance))
|
|
|
|
return false;
|
|
|
|
|
2015-01-08 05:50:38 +01:00
|
|
|
if (mFlags & LC_PIECE_PLACEHOLDER)
|
|
|
|
return true;
|
|
|
|
|
2014-12-26 16:44:46 +01:00
|
|
|
lcVector3 Intersection;
|
|
|
|
|
|
|
|
return mMesh->MinIntersectDist(Start, End, MinDistance, Intersection);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PieceInfo::BoxTest(const lcMatrix44& WorldMatrix, const lcVector4 WorldPlanes[6]) const
|
|
|
|
{
|
|
|
|
lcMatrix44 InverseWorldMatrix = lcMatrix44AffineInverse(WorldMatrix);
|
|
|
|
|
|
|
|
const int NumCorners = 8;
|
|
|
|
const int NumPlanes = 6;
|
|
|
|
lcVector4 LocalPlanes[NumPlanes];
|
|
|
|
|
|
|
|
for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++)
|
|
|
|
{
|
|
|
|
lcVector3 PlaneNormal = lcMul30(WorldPlanes[PlaneIdx], InverseWorldMatrix);
|
|
|
|
LocalPlanes[PlaneIdx] = lcVector4(PlaneNormal, WorldPlanes[PlaneIdx][3] - lcDot3(InverseWorldMatrix[3], PlaneNormal));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
return mModel->SubModelBoxTest(LocalPlanes);
|
|
|
|
|
|
|
|
lcVector3 Box[NumCorners] =
|
|
|
|
{
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[2])
|
|
|
|
};
|
|
|
|
|
|
|
|
int Outcodes[NumCorners];
|
|
|
|
|
|
|
|
for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++)
|
|
|
|
{
|
|
|
|
Outcodes[CornerIdx] = 0;
|
|
|
|
|
|
|
|
for (int PlaneIdx = 0; PlaneIdx < NumPlanes; PlaneIdx++)
|
|
|
|
{
|
|
|
|
if (lcDot3(Box[CornerIdx], LocalPlanes[PlaneIdx]) + LocalPlanes[PlaneIdx][3] > 0)
|
|
|
|
Outcodes[CornerIdx] |= 1 << PlaneIdx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int OutcodesOR = 0, OutcodesAND = 0x3f;
|
|
|
|
|
|
|
|
for (int CornerIdx = 0; CornerIdx < NumCorners; CornerIdx++)
|
|
|
|
{
|
|
|
|
OutcodesAND &= Outcodes[CornerIdx];
|
|
|
|
OutcodesOR |= Outcodes[CornerIdx];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OutcodesAND != 0)
|
|
|
|
return false;
|
|
|
|
|
2015-01-08 05:50:38 +01:00
|
|
|
if (mFlags & LC_PIECE_PLACEHOLDER)
|
|
|
|
return OutcodesOR == 0;
|
|
|
|
|
2014-12-26 16:44:46 +01:00
|
|
|
return OutcodesOR == 0 || mMesh->IntersectsPlanes(LocalPlanes);
|
|
|
|
}
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
// Zoom extents for the preview window and print catalog
|
2015-01-02 12:58:14 +01:00
|
|
|
void PieceInfo::ZoomExtents(const lcMatrix44& ProjectionMatrix, lcMatrix44& ViewMatrix, float* EyePos) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-06-21 02:41:53 +02:00
|
|
|
lcVector3 Points[8] =
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-06-21 02:41:53 +02:00
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[1], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[4], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[2]),
|
|
|
|
lcVector3(m_fDimensions[0], m_fDimensions[4], m_fDimensions[5]),
|
|
|
|
lcVector3(m_fDimensions[3], m_fDimensions[1], m_fDimensions[2])
|
|
|
|
};
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-06-21 02:41:53 +02:00
|
|
|
lcVector3 Center(GetCenter());
|
|
|
|
lcVector3 Position;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-06-21 02:41:53 +02:00
|
|
|
if (EyePos)
|
|
|
|
Position = lcVector3(EyePos[0], EyePos[1], EyePos[2]);
|
|
|
|
else
|
2014-08-30 21:48:36 +02:00
|
|
|
Position = lcVector3(-250.0f, -250.0f, 75.0f);
|
2012-06-21 02:41:53 +02:00
|
|
|
Position += Center;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-06-21 02:41:53 +02:00
|
|
|
lcMatrix44 ModelView = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1));
|
2015-01-02 12:58:14 +01:00
|
|
|
Position = lcZoomExtents(Position, ModelView, ProjectionMatrix, Points, 8);
|
|
|
|
ViewMatrix = lcMatrix44LookAt(Position, Center, lcVector3(0, 0, 1));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (EyePos)
|
|
|
|
{
|
2012-06-21 02:41:53 +02:00
|
|
|
EyePos[0] = Position[0];
|
|
|
|
EyePos[1] = Position[1];
|
|
|
|
EyePos[2] = Position[2];
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-24 16:52:52 +01:00
|
|
|
void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected)
|
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
{
|
2014-12-26 16:44:46 +01:00
|
|
|
mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected);
|
2014-12-24 16:52:52 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcRenderMesh RenderMesh;
|
|
|
|
|
|
|
|
RenderMesh.WorldMatrix = WorldMatrix;
|
2015-01-08 05:50:38 +01:00
|
|
|
RenderMesh.Mesh = (mFlags & LC_PIECE_PLACEHOLDER) ? gPlaceholderMesh : mMesh;
|
2014-12-24 16:52:52 +01:00
|
|
|
RenderMesh.ColorIndex = ColorIndex;
|
|
|
|
RenderMesh.Focused = Focused;
|
|
|
|
RenderMesh.Selected = Selected;
|
|
|
|
|
|
|
|
bool Translucent = lcIsColorTranslucent(ColorIndex);
|
|
|
|
|
|
|
|
if ((mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_LINES)) || ((mFlags & LC_PIECE_HAS_DEFAULT) && !Translucent))
|
2015-02-08 19:54:51 +01:00
|
|
|
Scene.mOpaqueMeshes.Add(RenderMesh);
|
2014-12-24 16:52:52 +01:00
|
|
|
|
|
|
|
if ((mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
|
|
|
|
{
|
2015-02-08 19:54:51 +01:00
|
|
|
lcVector3 Pos = lcMul31(WorldMatrix[3], Scene.mViewMatrix);
|
2014-12-24 16:52:52 +01:00
|
|
|
|
|
|
|
RenderMesh.Distance = Pos[2];
|
|
|
|
|
2015-02-08 19:54:51 +01:00
|
|
|
Scene.mTranslucentMeshes.Add(RenderMesh);
|
2014-04-23 16:53:43 +02:00
|
|
|
}
|
|
|
|
}
|
2014-12-30 17:30:12 +01:00
|
|
|
|
|
|
|
void PieceInfo::GetPartsList(int DefaultColorIndex, lcArray<lcPartsListEntry>& PartsList) const
|
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
{
|
|
|
|
mModel->GetPartsList(DefaultColorIndex, PartsList);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int UsedIdx = 0; UsedIdx < PartsList.GetSize(); UsedIdx++)
|
|
|
|
{
|
|
|
|
if (PartsList[UsedIdx].Info != this || PartsList[UsedIdx].ColorIndex != DefaultColorIndex)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
PartsList[UsedIdx].Count++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcPartsListEntry& PartsListEntry = PartsList.Add();
|
|
|
|
|
|
|
|
PartsListEntry.Info = const_cast<PieceInfo*>(this);
|
|
|
|
PartsListEntry.ColorIndex = DefaultColorIndex;
|
|
|
|
PartsListEntry.Count = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PieceInfo::GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcArray<lcModelPartsEntry>& ModelParts) const
|
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
|
|
|
{
|
|
|
|
mModel->GetModelParts(WorldMatrix, DefaultColorIndex, ModelParts);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
lcModelPartsEntry& ModelPartsEntry = ModelParts.Add();
|
|
|
|
ModelPartsEntry.WorldMatrix = WorldMatrix;
|
|
|
|
ModelPartsEntry.ColorIndex = DefaultColorIndex;
|
|
|
|
ModelPartsEntry.Info = const_cast<PieceInfo*>(this);
|
|
|
|
}
|
2015-01-02 17:44:01 +01:00
|
|
|
|
2015-01-17 19:29:10 +01:00
|
|
|
void PieceInfo::UpdateBoundingBox(lcArray<lcModel*>& UpdatedModels)
|
2015-01-02 17:44:01 +01:00
|
|
|
{
|
|
|
|
if (mFlags & LC_PIECE_MODEL)
|
2015-01-17 19:29:10 +01:00
|
|
|
mModel->UpdatePieceInfo(UpdatedModels);
|
2015-01-02 17:44:01 +01:00
|
|
|
}
|