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 04:20:27 +02:00
|
|
|
#include "lc_mesh.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <float.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include "opengl.h"
|
|
|
|
#include "pieceinf.h"
|
2012-10-12 01:55:55 +02:00
|
|
|
#include "lc_texture.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "piece.h"
|
|
|
|
#include "camera.h"
|
|
|
|
#include "light.h"
|
|
|
|
#include "group.h"
|
|
|
|
#include "terrain.h"
|
|
|
|
#include "project.h"
|
|
|
|
#include "image.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "minifig.h"
|
2013-08-16 03:25:51 +02:00
|
|
|
#include "lc_mainwindow.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "view.h"
|
2012-10-02 03:23:44 +02:00
|
|
|
#include "lc_library.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
#include "texfont.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "lc_application.h"
|
2013-08-09 06:57:18 +02:00
|
|
|
#include "lc_profile.h"
|
2014-04-14 05:20:16 +02:00
|
|
|
#include "lc_context.h"
|
|
|
|
#include "preview.h"
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
Project::Project()
|
|
|
|
{
|
|
|
|
m_bModified = false;
|
|
|
|
m_nTracking = LC_TRACK_NONE;
|
2013-08-09 06:57:18 +02:00
|
|
|
mDropPiece = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
m_pUndoList = NULL;
|
|
|
|
m_pRedoList = NULL;
|
2013-08-09 06:57:18 +02:00
|
|
|
mTransformType = LC_TRANSFORM_RELATIVE_TRANSLATION;
|
2011-09-07 23:06:51 +02:00
|
|
|
m_pTerrain = new Terrain();
|
2012-10-12 20:21:45 +02:00
|
|
|
m_pBackground = new lcTexture();
|
2013-08-31 23:58:47 +02:00
|
|
|
mGridTexture = new lcTexture();
|
2013-08-09 06:57:18 +02:00
|
|
|
memset(&mSearchOptions, 0, sizeof(mSearchOptions));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
m_pScreenFont = new TexFont();
|
|
|
|
}
|
|
|
|
|
|
|
|
Project::~Project()
|
|
|
|
{
|
|
|
|
DeleteContents(false);
|
|
|
|
|
|
|
|
delete m_pTerrain;
|
|
|
|
delete m_pBackground;
|
2013-08-31 23:58:47 +02:00
|
|
|
delete mGridTexture;
|
2011-09-07 23:06:51 +02:00
|
|
|
delete m_pScreenFont;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::UpdateInterface()
|
|
|
|
{
|
|
|
|
// Update all user interface elements.
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateUndoRedo(m_pUndoList->pNext ? m_pUndoList->strText : NULL, m_pRedoList ? m_pRedoList->strText : NULL);
|
|
|
|
gMainWindow->UpdatePaste(g_App->mClipboard != NULL);
|
|
|
|
gMainWindow->UpdateCategories();
|
|
|
|
gMainWindow->UpdateTitle(m_strTitle, m_bModified);
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(gMainWindow->GetTool());
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateTransformType(mTransformType);
|
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
|
|
|
gMainWindow->UpdateSnap();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
|
|
|
gMainWindow->UpdatePerspective();
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
UpdateSelection();
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int i = 0; i < Views.GetSize(); i++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
Views[i]->MakeCurrent();
|
2011-09-07 23:06:51 +02:00
|
|
|
RenderInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateSelection();
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void Project::SetTitle(const char* Title)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
strcpy(m_strTitle, Title);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateTitle(m_strTitle, m_bModified);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Project::DeleteContents(bool bUndo)
|
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.LoadDefaults();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (!bUndo)
|
|
|
|
{
|
|
|
|
LC_UNDOINFO* pUndo;
|
|
|
|
|
|
|
|
while (m_pUndoList)
|
|
|
|
{
|
|
|
|
pUndo = m_pUndoList;
|
|
|
|
m_pUndoList = m_pUndoList->pNext;
|
|
|
|
delete pUndo;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (m_pRedoList)
|
|
|
|
{
|
|
|
|
pUndo = m_pRedoList;
|
|
|
|
m_pRedoList = m_pRedoList->pNext;
|
|
|
|
delete pUndo;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pRedoList = NULL;
|
|
|
|
m_pUndoList = NULL;
|
|
|
|
|
|
|
|
m_pBackground->Unload();
|
2011-09-20 01:03:28 +02:00
|
|
|
m_pTerrain->LoadDefaults(true);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
mPieces.DeleteAll();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-12-13 01:20:40 +01:00
|
|
|
if (!bUndo)
|
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
|
2012-12-13 01:20:40 +01:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
View* view = Views[ViewIdx];
|
2012-12-13 01:20:40 +01:00
|
|
|
|
|
|
|
if (!view->mCamera->IsSimple())
|
|
|
|
view->SetDefaultCamera();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-09 00:34:50 +02:00
|
|
|
mCameras.DeleteAll();
|
|
|
|
mLights.DeleteAll();
|
2014-05-25 03:45:19 +02:00
|
|
|
mGroups.DeleteAll();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Only call after DeleteContents()
|
|
|
|
void Project::LoadDefaults(bool cameras)
|
|
|
|
{
|
|
|
|
int i;
|
2014-02-10 01:13:41 +01:00
|
|
|
|
|
|
|
mProperties.LoadDefaults();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
// Default values
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->SetColorIndex(lcGetColorIndex(4));
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_SELECT);
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->SetAddKeys(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
m_bUndoOriginal = true;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateUndoRedo(NULL, NULL);
|
|
|
|
m_nAngleSnap = (unsigned short)lcGetProfileInt(LC_PROFILE_ANGLE_SNAP);
|
|
|
|
m_nSnap = lcGetProfileInt(LC_PROFILE_SNAP);
|
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2011-09-07 23:06:51 +02:00
|
|
|
m_nMoveSnap = 0x0304;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateSnap();
|
2011-09-07 23:06:51 +02:00
|
|
|
m_nCurStep = 1;
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(1, 255);
|
2013-08-09 06:57:18 +02:00
|
|
|
strcpy(m_strHeader, "");
|
|
|
|
strcpy(m_strFooter, "Page &P");
|
2011-09-20 01:03:28 +02:00
|
|
|
m_pTerrain->LoadDefaults(true);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (i = 0; i < Views.GetSize (); i++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
Views[i]->MakeCurrent();
|
2011-09-07 23:06:51 +02:00
|
|
|
RenderInitialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cameras)
|
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
for (i = 0; i < Views.GetSize(); i++)
|
|
|
|
if (!Views[i]->mCamera->IsSimple())
|
|
|
|
Views[i]->SetDefaultCamera();
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
SystemPieceComboAdd(NULL);
|
|
|
|
UpdateSelection();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Standard file menu commands
|
|
|
|
|
|
|
|
// Read a .lcd file
|
2012-03-23 00:44:56 +01:00
|
|
|
bool Project::FileLoad(lcFile* file, bool bUndo, bool bMerge)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
lcint32 i, count;
|
2011-09-07 23:06:51 +02:00
|
|
|
char id[32];
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint32 rgb;
|
2011-09-07 23:06:51 +02:00
|
|
|
float fv = 0.4f;
|
2014-05-23 02:02:21 +02:00
|
|
|
lcuint8 ch;
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint16 sh;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
file->Seek(0, SEEK_SET);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(id, 32);
|
2011-09-07 23:06:51 +02:00
|
|
|
sscanf(&id[7], "%f", &fv);
|
|
|
|
|
|
|
|
// Fix the ugly floating point reading on computers with different decimal points.
|
|
|
|
if (fv == 0.0f)
|
|
|
|
{
|
|
|
|
lconv *loc = localeconv();
|
|
|
|
id[8] = loc->decimal_point[0];
|
|
|
|
sscanf(&id[7], "%f", &fv);
|
|
|
|
|
|
|
|
if (fv == 0.0f)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fv > 0.4f)
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadFloats(&fv, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
if (!bMerge)
|
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mBackgroundSolidColor[0] = (float)((unsigned char) (rgb))/255;
|
|
|
|
mProperties.mBackgroundSolidColor[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
|
|
|
|
mProperties.mBackgroundSolidColor[2] = (float)((unsigned char) ((rgb) >> 16))/255;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fv < 0.6f) // old view
|
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
Camera* pCam = new Camera(false);
|
2012-08-22 03:13:32 +02:00
|
|
|
pCam->CreateName(mCameras);
|
|
|
|
mCameras.Add(pCam);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
double eye[3], target[3];
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadDoubles(eye, 3);
|
|
|
|
file->ReadDoubles(target, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
float tmp[3] = { (float)eye[0], (float)eye[1], (float)eye[2] };
|
2014-01-30 04:13:34 +01:00
|
|
|
pCam->ChangeKey(1, false, tmp, LC_CK_EYE);
|
2011-09-07 23:06:51 +02:00
|
|
|
tmp[0] = (float)target[0]; tmp[1] = (float)target[1]; tmp[2] = (float)target[2];
|
2014-01-30 04:13:34 +01:00
|
|
|
pCam->ChangeKey(1, false, tmp, LC_CK_TARGET);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
// Create up vector
|
2012-03-29 03:10:55 +02:00
|
|
|
lcVector3 UpVector(0, 0, 1), FrontVector((float)(eye[0] - target[0]), (float)(eye[1] - target[1]), (float)(eye[2] - target[2])), SideVector;
|
|
|
|
FrontVector.Normalize();
|
|
|
|
if (FrontVector == UpVector)
|
|
|
|
SideVector = lcVector3(1, 0, 0);
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
2012-03-29 03:10:55 +02:00
|
|
|
SideVector = lcCross(FrontVector, UpVector);
|
|
|
|
UpVector = lcNormalize(lcCross(SideVector, FrontVector));
|
2014-01-30 04:13:34 +01:00
|
|
|
pCam->ChangeKey(1, false, UpVector, LC_CK_UP);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bMerge)
|
|
|
|
file->Seek(32, SEEK_CUR);
|
|
|
|
else
|
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
lcuint32 u;
|
2014-02-10 01:13:41 +01:00
|
|
|
float f;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&i, 1); m_nAngleSnap = i;
|
2013-08-09 06:57:18 +02:00
|
|
|
file->ReadU32(&u, 1); //m_nSnap
|
2014-02-10 01:13:41 +01:00
|
|
|
file->ReadFloats(&f, 1); //m_fLineWidth
|
2013-08-09 06:57:18 +02:00
|
|
|
file->ReadU32(&u, 1); //m_nDetail
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&i, 1); //m_nCurGroup = i;
|
2013-08-09 06:57:18 +02:00
|
|
|
file->ReadS32(&i, 1); //m_nCurColor = i;
|
2014-05-01 16:55:12 +02:00
|
|
|
file->ReadS32(&i, 1); //action = i;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&i, 1); m_nCurStep = i;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fv > 0.8f)
|
2014-02-10 01:13:41 +01:00
|
|
|
file->ReadU32();//m_nScene
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&count, 1);
|
2013-08-09 06:57:18 +02:00
|
|
|
// SystemStartProgressBar(0, count, 1, "Loading project...");
|
2012-11-09 01:07:53 +01:00
|
|
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
|
|
|
Library->OpenCache();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
int FirstNewPiece = mPieces.GetSize();
|
2013-12-19 14:41:49 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
while (count--)
|
2013-01-06 20:24:25 +01:00
|
|
|
{
|
2011-09-07 23:06:51 +02:00
|
|
|
if (fv > 0.4f)
|
|
|
|
{
|
|
|
|
Piece* pPiece = new Piece(NULL);
|
2013-08-09 06:57:18 +02:00
|
|
|
pPiece->FileLoad(*file);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-11-09 01:07:53 +01:00
|
|
|
if (bMerge)
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
if (strcmp(mPieces[PieceIdx]->GetName(), pPiece->GetName()) == 0)
|
2012-11-09 01:07:53 +01:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
pPiece->CreateName(mPieces);
|
2012-11-09 01:07:53 +01:00
|
|
|
break;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-11-09 01:07:53 +01:00
|
|
|
if (strlen(pPiece->GetName()) == 0)
|
2014-04-10 06:46:48 +02:00
|
|
|
pPiece->CreateName(mPieces);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
mPieces.Add(pPiece);
|
2012-11-09 01:07:53 +01:00
|
|
|
if (!bUndo)
|
2013-08-09 06:57:18 +02:00
|
|
|
SystemPieceComboAdd(pPiece->mPieceInfo->m_strDescription);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char name[LC_PIECE_NAME_LEN];
|
2012-10-18 20:57:21 +02:00
|
|
|
float pos[3], rot[3];
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint8 color, step, group;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadFloats(pos, 3);
|
|
|
|
file->ReadFloats(rot, 3);
|
|
|
|
file->ReadU8(&color, 1);
|
2012-07-02 01:38:53 +02:00
|
|
|
file->ReadBuffer(name, 9);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU8(&step, 1);
|
|
|
|
file->ReadU8(&group, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-11-09 01:07:53 +01:00
|
|
|
PieceInfo* pInfo = Library->FindPiece(name, true);
|
|
|
|
Piece* pPiece = new Piece(pInfo);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->Initialize(pos[0], pos[1], pos[2], step);
|
2012-11-09 01:07:53 +01:00
|
|
|
pPiece->SetColorCode(lcGetColorCodeFromOriginalColor(color));
|
2014-04-10 06:46:48 +02:00
|
|
|
pPiece->CreateName(mPieces);
|
2014-05-01 16:55:12 +02:00
|
|
|
mPieces.Add(pPiece);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2012-11-09 01:07:53 +01:00
|
|
|
lcMatrix44 ModelWorld = lcMul(lcMatrix44RotationZ(rot[2] * LC_DTOR), lcMul(lcMatrix44RotationY(rot[1] * LC_DTOR), lcMatrix44RotationX(rot[0] * LC_DTOR)));
|
|
|
|
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld);
|
|
|
|
AxisAngle[3] *= LC_RTOD;
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION);
|
2012-11-09 01:07:53 +01:00
|
|
|
// pPiece->SetGroup((Group*)group);
|
|
|
|
SystemPieceComboAdd(pInfo->m_strDescription);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2012-11-09 01:07:53 +01:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
// SytemStepProgressBar();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2012-11-09 01:07:53 +01:00
|
|
|
|
|
|
|
Library->CloseCache();
|
2013-08-09 06:57:18 +02:00
|
|
|
// SytemEndProgressBar();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (!bMerge)
|
|
|
|
{
|
|
|
|
if (fv >= 0.4f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
if (sh > 100)
|
|
|
|
file->Seek(sh, SEEK_CUR);
|
|
|
|
else
|
2014-02-10 01:13:41 +01:00
|
|
|
{
|
|
|
|
file->ReadBuffer(mProperties.mAuthor.GetBuffer(sh), sh);
|
|
|
|
mProperties.mAuthor.Buffer()[sh] = 0;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
if (sh > 100)
|
|
|
|
file->Seek(sh, SEEK_CUR);
|
|
|
|
else
|
2014-02-10 01:13:41 +01:00
|
|
|
{
|
|
|
|
file->ReadBuffer(mProperties.mDescription.GetBuffer(sh), sh);
|
|
|
|
mProperties.mDescription.Buffer()[sh] = 0;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF && fv < 1.3f) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
if (sh > 255)
|
|
|
|
file->Seek(sh, SEEK_CUR);
|
|
|
|
else
|
2014-02-10 01:13:41 +01:00
|
|
|
{
|
|
|
|
file->ReadBuffer(mProperties.mComments.GetBuffer(sh), sh);
|
|
|
|
mProperties.mComments.Buffer()[sh] = 0;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (fv >= 0.4f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
file->Seek (sh, SEEK_CUR);
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
file->Seek (sh, SEEK_CUR);
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
if (ch == 0xFF && fv < 1.3f) file->ReadU16(&sh, 1); else sh = ch;
|
2011-09-07 23:06:51 +02:00
|
|
|
file->Seek (sh, SEEK_CUR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fv >= 0.5f)
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
int NumGroups = mGroups.GetSize();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
file->ReadS32(&count, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
for (i = 0; i < count; i++)
|
2014-05-25 03:45:19 +02:00
|
|
|
mGroups.Add(new lcGroup());
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = NumGroups; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
if (fv < 1.0f)
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
file->ReadBuffer(Group->m_strName, 65);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
2014-05-25 03:45:19 +02:00
|
|
|
Group->mGroup = (lcGroup*)-1;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
2014-05-25 03:45:19 +02:00
|
|
|
Group->FileLoad(file);
|
2013-12-19 14:41:49 +01:00
|
|
|
|
|
|
|
if (bMerge)
|
|
|
|
{
|
|
|
|
// Ensure a unique group name
|
|
|
|
|
|
|
|
int max = -1;
|
|
|
|
String baseName;
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int Existing = 0; Existing < GroupIdx; Existing++)
|
|
|
|
max = lcMax(max, InstanceOfName(mGroups[Existing]->m_strName, Group->m_strName, baseName));
|
2013-12-19 14:41:49 +01:00
|
|
|
|
|
|
|
if (max > -1)
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
int baseReserve = sizeof(Group->m_strName) - 5; // space, #, 2-digits, and terminating 0
|
2013-12-19 14:41:49 +01:00
|
|
|
for (int num = max; (num > 99); num /= 10) { baseReserve--; }
|
2014-05-25 03:45:19 +02:00
|
|
|
sprintf(Group->m_strName, "%s #%.2d", (const char*)(baseName.Left(baseReserve)), max+1);
|
2013-12-19 14:41:49 +01:00
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = NumGroups; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
|
|
|
|
i = LC_POINTER_TO_INT(Group->mGroup);
|
|
|
|
Group->mGroup = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (i > 0xFFFF || i == -1)
|
|
|
|
continue;
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
Group->mGroup = mGroups[NumGroups + i];
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = FirstNewPiece; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
i = LC_POINTER_TO_INT(Piece->GetGroup());
|
|
|
|
Piece->SetGroup(NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (i > 0xFFFF || i == -1)
|
|
|
|
continue;
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
Piece->SetGroup(mGroups[NumGroups + i]);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
RemoveEmptyGroups();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bMerge)
|
|
|
|
{
|
|
|
|
if (fv >= 0.6f)
|
|
|
|
{
|
|
|
|
if (fv < 1.0f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint32 ViewportMode;
|
|
|
|
file->ReadU32(&ViewportMode, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-02-05 03:50:57 +01:00
|
|
|
lcuint8 ViewportMode, ActiveViewport;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU8(&ViewportMode, 1);
|
|
|
|
file->ReadU8(&ActiveViewport, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&count, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
for (i = 0; i < count; i++)
|
2012-08-23 20:47:37 +02:00
|
|
|
mCameras.Add(new Camera(false));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (count < 7)
|
|
|
|
{
|
2012-08-23 20:47:37 +02:00
|
|
|
Camera* pCam = new Camera(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
pCam->FileLoad(*file);
|
|
|
|
delete pCam;
|
|
|
|
}
|
|
|
|
else
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
mCameras[CameraIdx]->FileLoad(*file);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fv >= 0.7f)
|
|
|
|
{
|
|
|
|
for (count = 0; count < 4; count++)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadS32(&i, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-07-02 01:38:53 +02:00
|
|
|
// Camera* pCam = m_pCameras;
|
|
|
|
// while (i--)
|
|
|
|
// pCam = pCam->m_pNext;
|
2012-02-05 03:50:57 +01:00
|
|
|
// m_pViewCameras[count] = pCam;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mFogColor[0] = (float)((unsigned char) (rgb))/255;
|
|
|
|
mProperties.mFogColor[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
|
|
|
|
mProperties.mFogColor[2] = (float)((unsigned char) ((rgb) >> 16))/255;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (fv < 1.0f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mFogDensity = (float)rgb/100;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
2014-02-10 01:13:41 +01:00
|
|
|
file->ReadFloats(&mProperties.mFogDensity, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (fv < 1.3f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU8(&ch, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
if (ch == 0xFF)
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU16(&sh, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
sh = ch;
|
|
|
|
}
|
|
|
|
else
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU16(&sh, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (sh < LC_MAXPATH)
|
2014-04-16 02:35:55 +02:00
|
|
|
{
|
|
|
|
char Background[LC_MAXPATH];
|
|
|
|
file->ReadBuffer(Background, sh);
|
|
|
|
mProperties.mBackgroundImage = Background;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
|
|
|
file->Seek (sh, SEEK_CUR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fv >= 0.8f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
file->ReadBuffer(m_strHeader, ch);
|
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
file->ReadBuffer(m_strFooter, ch);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fv > 0.9f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mAmbientColor[0] = (float)((unsigned char) (rgb))/255;
|
|
|
|
mProperties.mAmbientColor[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
|
|
|
|
mProperties.mAmbientColor[2] = (float)((unsigned char) ((rgb) >> 16))/255;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (fv < 1.3f)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
file->ReadS32(&i, 1); // m_bAnimation = (i != 0);
|
|
|
|
file->ReadS32(&i, 1); // mAddKeys = (i != 0);
|
2014-01-30 04:13:34 +01:00
|
|
|
file->ReadU8(&ch, 1); // m_nFPS
|
|
|
|
file->ReadS32(&i, 1); // m_nCurFrame = i;
|
|
|
|
file->ReadU16(&sh, 1); // m_nTotalFrames
|
2014-05-21 00:15:42 +02:00
|
|
|
file->ReadS32(&i, 1); // m_nGridSize = i;
|
|
|
|
file->ReadS32(&i, 1); // m_nMoveSnap = i;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
file->ReadU8(&ch, 1); // m_bAnimation = (ch != 0);
|
|
|
|
file->ReadU8(&ch, 1); // mAddKeys = (ch != 0);
|
2014-01-30 04:13:34 +01:00
|
|
|
file->ReadU8(&ch, 1); // m_nFPS
|
|
|
|
file->ReadU16(&sh, 1); // m_nCurFrame
|
|
|
|
file->ReadU16(&sh, 1); // m_nTotalFrames
|
2013-08-31 23:58:47 +02:00
|
|
|
file->ReadU16(&sh, 1); // m_nGridSize = sh;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU16(&sh, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
if (fv >= 1.4f)
|
|
|
|
m_nMoveSnap = sh;
|
|
|
|
}
|
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
if (fv > 1.0f)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mBackgroundGradientColor1[0] = (float)((unsigned char) (rgb))/255;
|
|
|
|
mProperties.mBackgroundGradientColor1[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
|
|
|
|
mProperties.mBackgroundGradientColor1[2] = (float)((unsigned char) ((rgb) >> 16))/255;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->ReadU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
mProperties.mBackgroundGradientColor2[0] = (float)((unsigned char) (rgb))/255;
|
|
|
|
mProperties.mBackgroundGradientColor2[1] = (float)((unsigned char) (((unsigned short) (rgb)) >> 8))/255;
|
|
|
|
mProperties.mBackgroundGradientColor2[2] = (float)((unsigned char) ((rgb) >> 16))/255;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
if (fv > 1.1f)
|
|
|
|
m_pTerrain->FileLoad (file);
|
|
|
|
else
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
file->Seek(4, SEEK_CUR);
|
|
|
|
file->ReadBuffer(&ch, 1);
|
|
|
|
file->Seek(ch, SEEK_CUR);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (i = 0; i < Views.GetSize (); i++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
Views[i]->MakeCurrent();
|
2011-09-07 23:06:51 +02:00
|
|
|
RenderInitialize();
|
|
|
|
}
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
CalculateStep();
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
if (!bUndo)
|
|
|
|
SelectAndFocusNone(false);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
if (!bMerge)
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2012-12-13 01:20:40 +01:00
|
|
|
|
|
|
|
if (!bMerge)
|
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
|
2012-12-13 01:20:40 +01:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
View* view = Views[ViewIdx];
|
2012-12-13 01:20:40 +01:00
|
|
|
|
|
|
|
if (!view->mCamera->IsSimple())
|
|
|
|
view->SetDefaultCamera();
|
|
|
|
}
|
|
|
|
|
2012-12-14 00:58:03 +01:00
|
|
|
if (!bUndo)
|
2014-05-03 23:16:48 +02:00
|
|
|
ZoomExtents(0, Views.GetSize());
|
2012-12-13 01:20:40 +01:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
|
|
|
gMainWindow->UpdateSnap();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
2011-09-07 23:06:51 +02:00
|
|
|
UpdateSelection();
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
void Project::FileSave(lcFile* file, bool bUndo)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
float ver_flt = 1.4f; // LeoCAD 0.75 - (and this should have been an integer).
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint32 rgb;
|
|
|
|
lcuint8 ch;
|
|
|
|
lcuint16 sh;
|
2011-09-07 23:06:51 +02:00
|
|
|
int i, j;
|
|
|
|
|
2013-08-17 00:39:47 +02:00
|
|
|
const char LC_STR_VERSION[32] = "LeoCAD 0.7 Project\0\0";
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->Seek(0, SEEK_SET);
|
|
|
|
file->WriteBuffer(LC_STR_VERSION, 32);
|
|
|
|
file->WriteFloats(&ver_flt, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
rgb = LC_FLOATRGB(mProperties.mBackgroundSolidColor);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&rgb, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
i = m_nAngleSnap; file->WriteS32(&i, 1);
|
|
|
|
file->WriteU32(&m_nSnap, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteFloat(1.0f);//m_fLineWidth
|
|
|
|
file->WriteU32(0); // m_nDetail
|
2013-08-09 06:57:18 +02:00
|
|
|
i = 0;//i = m_nCurGroup;
|
|
|
|
file->WriteS32(&i, 1);
|
|
|
|
i = 0;//i = m_nCurColor;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteS32(&i, 1);
|
2014-05-23 02:02:21 +02:00
|
|
|
i = 0; file->WriteS32(&i, 1); // m_nCurAction
|
2012-03-23 00:44:56 +01:00
|
|
|
i = m_nCurStep; file->WriteS32(&i, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteU32(0);//m_nScene
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-25 01:50:32 +02:00
|
|
|
file->WriteS32(mPieces.GetSize());
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
mPieces[PieceIdx]->FileSave(*file);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
const char* Author = mProperties.mAuthor.Buffer();
|
|
|
|
ch = lcMin(strlen(Author), 100U);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteBuffer(Author, ch);
|
|
|
|
const char* Description = mProperties.mDescription.Buffer();
|
|
|
|
ch = lcMin(strlen(Description), 100U);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteBuffer(Description, ch);
|
|
|
|
const char* Comments = mProperties.mComments.Buffer();
|
|
|
|
ch = lcMin(strlen(Comments), 255U);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteBuffer(Comments, ch);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
i = mGroups.GetSize();
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteS32(&i, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
mGroups[GroupIdx]->FileSave(file, mGroups);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-02-05 03:50:57 +01:00
|
|
|
lcuint8 ViewportMode = 0, ActiveViewport = 0;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU8(&ViewportMode, 1);
|
|
|
|
file->WriteU8(&ActiveViewport, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
i = mCameras.GetSize();
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteS32(&i, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
mCameras[CameraIdx]->FileSave(*file);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
{
|
2012-02-05 03:50:57 +01:00
|
|
|
i = 0;
|
|
|
|
// for (i = 0, pCamera = m_pCameras; pCamera; pCamera = pCamera->m_pNext)
|
|
|
|
// if (pCamera == m_pViewCameras[j])
|
|
|
|
// break;
|
|
|
|
// else
|
|
|
|
// i++;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteS32(&i, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
rgb = LC_FLOATRGB(mProperties.mFogColor);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteFloats(&mProperties.mFogDensity, 1);
|
2014-04-16 02:35:55 +02:00
|
|
|
sh = strlen(mProperties.mBackgroundImage.Buffer());
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU16(&sh, 1);
|
2014-04-16 02:35:55 +02:00
|
|
|
file->WriteBuffer(mProperties.mBackgroundImage.Buffer(), sh);
|
2011-09-07 23:06:51 +02:00
|
|
|
ch = strlen(m_strHeader);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
|
|
|
file->WriteBuffer(m_strHeader, ch);
|
2011-09-07 23:06:51 +02:00
|
|
|
ch = strlen(m_strFooter);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
|
|
|
file->WriteBuffer(m_strFooter, ch);
|
2011-09-07 23:06:51 +02:00
|
|
|
// 0.60 (1.0)
|
2014-02-10 01:13:41 +01:00
|
|
|
rgb = LC_FLOATRGB(mProperties.mAmbientColor);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&rgb, 1);
|
2014-05-21 00:15:42 +02:00
|
|
|
ch = 0;// m_bAnimation;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteBuffer(&ch, 1);
|
2014-05-21 00:15:42 +02:00
|
|
|
ch = 0;// mAddKeys;
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU8(&ch, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
file->WriteU8 (24); // m_nFPS
|
|
|
|
file->WriteU16(1); // m_nCurFrame
|
|
|
|
file->WriteU16(100); // m_nTotalFrames
|
2013-08-31 23:58:47 +02:00
|
|
|
file->WriteU16(0); // m_nGridSize
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU16(&m_nMoveSnap, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
// 0.62 (1.1)
|
2014-02-10 01:13:41 +01:00
|
|
|
rgb = LC_FLOATRGB(mProperties.mBackgroundGradientColor1);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&rgb, 1);
|
2014-02-10 01:13:41 +01:00
|
|
|
rgb = LC_FLOATRGB(mProperties.mBackgroundGradientColor2);
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&rgb, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
// 0.64 (1.2)
|
|
|
|
m_pTerrain->FileSave(file);
|
|
|
|
|
|
|
|
if (!bUndo)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
lcuint32 pos = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
/*
|
|
|
|
// TODO: add file preview
|
|
|
|
i = lcGetProfileValue("Default", "Save Preview", 0);
|
2013-01-06 20:24:25 +01:00
|
|
|
if (i != 0)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
pos = file->GetPosition();
|
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
Image* image = new Image[1];
|
2011-09-07 23:06:51 +02:00
|
|
|
LC_IMAGE_OPTS opts;
|
|
|
|
opts.interlaced = false;
|
|
|
|
opts.transparent = false;
|
|
|
|
opts.format = LC_IMAGE_GIF;
|
|
|
|
|
|
|
|
i = m_bAnimation ? m_nCurFrame : m_nCurStep;
|
|
|
|
CreateImages(image, 120, 100, i, i, false);
|
|
|
|
image[0].FileSave (*file, &opts);
|
|
|
|
delete []image;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
*/
|
2012-03-23 00:44:56 +01:00
|
|
|
file->WriteU32(&pos, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-16 01:43:18 +02:00
|
|
|
void Project::FileReadMPD(lcFile& MPD, lcArray<LC_FILEENTRY*>& FileArray) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
LC_FILEENTRY* CurFile = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
char Buf[1024];
|
|
|
|
|
|
|
|
while (MPD.ReadLine(Buf, 1024))
|
2012-03-23 00:44:56 +01:00
|
|
|
{
|
|
|
|
String Line(Buf);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
Line.TrimLeft();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
if (Line[0] != '0')
|
|
|
|
{
|
|
|
|
// Copy current line.
|
|
|
|
if (CurFile != NULL)
|
|
|
|
CurFile->File.WriteBuffer(Buf, strlen(Buf));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
continue;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
Line.TrimRight();
|
|
|
|
Line = Line.Right(Line.GetLength() - 1);
|
|
|
|
Line.TrimLeft();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
// Find where a subfile starts.
|
|
|
|
if (Line.CompareNoCase("FILE", 4) == 0)
|
|
|
|
{
|
|
|
|
Line = Line.Right(Line.GetLength() - 4);
|
|
|
|
Line.TrimLeft();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-03-23 00:44:56 +01:00
|
|
|
// Create a new file.
|
|
|
|
CurFile = new LC_FILEENTRY();
|
|
|
|
strncpy(CurFile->FileName, Line, sizeof(CurFile->FileName));
|
|
|
|
FileArray.Add(CurFile);
|
|
|
|
}
|
|
|
|
else if (Line.CompareNoCase("ENDFILE", 7) == 0)
|
|
|
|
{
|
|
|
|
// File ends here.
|
|
|
|
CurFile = NULL;
|
|
|
|
}
|
|
|
|
else if (CurFile != NULL)
|
|
|
|
{
|
|
|
|
// Copy current line.
|
|
|
|
CurFile->File.WriteBuffer(Buf, strlen(Buf));
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-16 01:43:18 +02:00
|
|
|
void Project::FileReadLDraw(lcFile* file, const lcMatrix44& CurrentTransform, int* nOk, int DefColor, int* nStep, lcArray<LC_FILEENTRY*>& FileArray)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-16 18:16:45 +02:00
|
|
|
char Line[1024];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-02-05 06:03:59 +01:00
|
|
|
// Save file offset.
|
|
|
|
lcuint32 Offset = file->GetPosition();
|
|
|
|
file->Seek(0, SEEK_SET);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
while (file->ReadLine(Line, 1024))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
bool read = true;
|
2013-08-16 18:16:45 +02:00
|
|
|
char* Ptr = Line;
|
|
|
|
char* Tokens[15];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
for (int TokenIdx = 0; TokenIdx < 15; TokenIdx++)
|
|
|
|
{
|
|
|
|
Tokens[TokenIdx] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
while (*Ptr && *Ptr <= 32)
|
|
|
|
{
|
|
|
|
*Ptr = 0;
|
|
|
|
Ptr++;
|
|
|
|
}
|
2012-10-18 20:57:21 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
Tokens[TokenIdx] = Ptr;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
while (*Ptr > 32)
|
|
|
|
Ptr++;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
if (!Tokens[0])
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
int LineType = atoi(Tokens[0]);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
if (LineType == 0)
|
|
|
|
{
|
|
|
|
if (Tokens[1])
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-16 18:16:45 +02:00
|
|
|
strupr(Tokens[1]);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
if (!strcmp(Tokens[1], "STEP"))
|
|
|
|
(*nStep)++;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LineType != 1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
bool Error = false;
|
|
|
|
for (int TokenIdx = 1; TokenIdx < 15; TokenIdx++)
|
|
|
|
{
|
|
|
|
if (!Tokens[TokenIdx])
|
2012-02-05 06:03:59 +01:00
|
|
|
{
|
2013-08-16 18:16:45 +02:00
|
|
|
Error = true;
|
|
|
|
break;
|
2012-02-05 06:03:59 +01:00
|
|
|
}
|
2013-08-16 18:16:45 +02:00
|
|
|
}
|
2012-02-05 06:03:59 +01:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
if (Error)
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
int ColorCode = atoi(Tokens[1]);
|
2012-02-05 06:03:59 +01:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
float Matrix[12];
|
|
|
|
for (int TokenIdx = 2; TokenIdx < 14; TokenIdx++)
|
|
|
|
Matrix[TokenIdx - 2] = atof(Tokens[TokenIdx]);
|
|
|
|
|
2013-12-08 00:15:28 +01:00
|
|
|
lcMatrix44 IncludeTransform(lcVector4(Matrix[3], Matrix[6], Matrix[9], 0.0f), lcVector4(Matrix[4], Matrix[7], Matrix[10], 0.0f),
|
|
|
|
lcVector4(Matrix[5], Matrix[8], Matrix[11], 0.0f), lcVector4(Matrix[0], Matrix[1], Matrix[2], 1.0f));
|
2013-08-16 18:16:45 +02:00
|
|
|
|
|
|
|
IncludeTransform = lcMul(IncludeTransform, CurrentTransform);
|
|
|
|
|
|
|
|
if (ColorCode == 16)
|
|
|
|
ColorCode = DefColor;
|
|
|
|
|
|
|
|
char* IncludeName = Tokens[14];
|
|
|
|
for (Ptr = IncludeName; *Ptr; Ptr++)
|
|
|
|
if (*Ptr == '\r' || *Ptr == '\n')
|
|
|
|
*Ptr = 0;
|
|
|
|
|
|
|
|
// See if it's a piece in the library
|
|
|
|
if (strlen(IncludeName) < LC_PIECE_NAME_LEN)
|
|
|
|
{
|
|
|
|
char name[LC_PIECE_NAME_LEN];
|
|
|
|
strcpy(name, IncludeName);
|
|
|
|
strupr(name);
|
|
|
|
|
|
|
|
Ptr = strrchr(name, '.');
|
|
|
|
if (Ptr != NULL)
|
|
|
|
*Ptr = 0;
|
2012-02-05 06:03:59 +01:00
|
|
|
|
2013-08-16 18:16:45 +02:00
|
|
|
PieceInfo* pInfo = lcGetPiecesLibrary()->FindPiece(name, false);
|
|
|
|
if (pInfo != NULL)
|
|
|
|
{
|
|
|
|
Piece* pPiece = new Piece(pInfo);
|
2012-02-05 06:03:59 +01:00
|
|
|
read = false;
|
|
|
|
|
2013-12-08 00:15:28 +01:00
|
|
|
float* Matrix = IncludeTransform;
|
|
|
|
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
|
|
|
|
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
|
|
|
|
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
|
2012-10-18 20:57:21 +02:00
|
|
|
AxisAngle[3] *= LC_RTOD;
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->Initialize(IncludeTransform[3].x / 25.0f, IncludeTransform[3].z / 25.0f, -IncludeTransform[3].y / 25.0f, *nStep);
|
2013-08-16 18:16:45 +02:00
|
|
|
pPiece->SetColorCode(ColorCode);
|
2014-04-10 06:46:48 +02:00
|
|
|
pPiece->CreateName(mPieces);
|
2014-05-01 16:55:12 +02:00
|
|
|
mPieces.Add(pPiece);
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION);
|
2013-08-16 18:16:45 +02:00
|
|
|
SystemPieceComboAdd(pInfo->m_strDescription);
|
2012-02-05 06:03:59 +01:00
|
|
|
(*nOk)++;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2013-08-16 18:16:45 +02:00
|
|
|
|
|
|
|
// Check for MPD files first.
|
|
|
|
if (read)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FileArray.GetSize(); i++)
|
|
|
|
{
|
|
|
|
if (stricmp(FileArray[i]->FileName, IncludeName) == 0)
|
|
|
|
{
|
|
|
|
FileReadLDraw(&FileArray[i]->File, IncludeTransform, nOk, ColorCode, nStep, FileArray);
|
|
|
|
read = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to read the file from disk.
|
|
|
|
if (read)
|
|
|
|
{
|
|
|
|
lcDiskFile tf;
|
|
|
|
|
|
|
|
if (tf.Open(IncludeName, "rt"))
|
|
|
|
{
|
|
|
|
FileReadLDraw(&tf, IncludeTransform, nOk, ColorCode, nStep, FileArray);
|
|
|
|
read = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (read)
|
|
|
|
{
|
|
|
|
// Create a placeholder.
|
|
|
|
char name[LC_PIECE_NAME_LEN];
|
|
|
|
strcpy(name, IncludeName);
|
|
|
|
strupr(name);
|
|
|
|
|
|
|
|
Ptr = strrchr(name, '.');
|
|
|
|
if (Ptr != NULL)
|
|
|
|
*Ptr = 0;
|
|
|
|
|
|
|
|
PieceInfo* Info = lcGetPiecesLibrary()->CreatePlaceholder(name);
|
|
|
|
|
|
|
|
Piece* pPiece = new Piece(Info);
|
|
|
|
read = false;
|
|
|
|
|
2013-12-08 00:15:28 +01:00
|
|
|
float* Matrix = IncludeTransform;
|
|
|
|
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
|
|
|
|
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
|
|
|
|
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
|
2013-08-16 18:16:45 +02:00
|
|
|
AxisAngle[3] *= LC_RTOD;
|
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->Initialize(IncludeTransform[3].x / 25.0f, IncludeTransform[3].z / 25.0f, -IncludeTransform[3].y / 25.0f, *nStep);
|
2013-08-16 18:16:45 +02:00
|
|
|
pPiece->SetColorCode(ColorCode);
|
2014-04-10 06:46:48 +02:00
|
|
|
pPiece->CreateName(mPieces);
|
2014-05-01 16:55:12 +02:00
|
|
|
mPieces.Add(pPiece);
|
2014-01-30 04:13:34 +01:00
|
|
|
pPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION);
|
2013-08-16 18:16:45 +02:00
|
|
|
SystemPieceComboAdd(Info->m_strDescription);
|
|
|
|
(*nOk)++;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-02-05 06:03:59 +01:00
|
|
|
// Restore file offset.
|
|
|
|
file->Seek(Offset, SEEK_SET);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
bool Project::DoSave(const char* FileName)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
char SaveFileName[LC_MAXPATH];
|
|
|
|
|
|
|
|
if (FileName && FileName[0])
|
|
|
|
strcpy(SaveFileName, FileName);
|
|
|
|
else
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
if (m_strPathName[0])
|
|
|
|
strcpy(SaveFileName, m_strPathName);
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
strcpy(SaveFileName, lcGetProfileString(LC_PROFILE_PROJECTS_PATH));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
int Length = strlen(SaveFileName);
|
|
|
|
if (Length && (SaveFileName[Length - 1] != '/' && SaveFileName[Length - 1] != '\\'))
|
|
|
|
strcat(SaveFileName, "/");
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
strcat(SaveFileName, m_strTitle);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
// check for dubious filename
|
2013-08-09 06:57:18 +02:00
|
|
|
int iBad = strcspn(SaveFileName, " #%;/\\");
|
2011-09-07 23:06:51 +02:00
|
|
|
if (iBad != -1)
|
2013-08-09 06:57:18 +02:00
|
|
|
SaveFileName[iBad] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
strcat(SaveFileName, ".lcd");
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_SAVE_PROJECT, SaveFileName))
|
|
|
|
return false;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
lcDiskFile file;
|
|
|
|
if (!file.Open(SaveFileName, "wb"))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
// MessageBox("Failed to save.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
char ext[4];
|
2011-09-07 23:06:51 +02:00
|
|
|
memset(ext, 0, 4);
|
2013-08-09 06:57:18 +02:00
|
|
|
const char* ptr = strrchr(SaveFileName, '.');
|
2011-09-07 23:06:51 +02:00
|
|
|
if (ptr != NULL)
|
|
|
|
{
|
|
|
|
strncpy(ext, ptr+1, 3);
|
|
|
|
strlwr(ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((strcmp(ext, "dat") == 0) || (strcmp(ext, "ldr") == 0))
|
|
|
|
{
|
|
|
|
int i, steps = GetLastStep();
|
2013-02-13 00:36:30 +01:00
|
|
|
char buf[256];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
ptr = strrchr(m_strPathName, '\\');
|
|
|
|
if (ptr == NULL)
|
|
|
|
ptr = strrchr(m_strPathName, '/');
|
|
|
|
if (ptr == NULL)
|
|
|
|
ptr = m_strPathName;
|
|
|
|
else
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
sprintf(buf, "0 Model exported from LeoCAD\r\n"
|
|
|
|
"0 Original name: %s\r\n", ptr);
|
2014-02-10 01:13:41 +01:00
|
|
|
if (!mProperties.mAuthor.IsEmpty())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
strcat(buf, "0 Author: ");
|
2014-02-10 01:13:41 +01:00
|
|
|
strcat(buf, mProperties.mAuthor.Buffer());
|
2011-09-07 23:06:51 +02:00
|
|
|
strcat(buf, "\r\n");
|
|
|
|
}
|
|
|
|
strcat(buf, "\r\n");
|
2012-03-23 00:44:56 +01:00
|
|
|
file.WriteBuffer(buf, strlen(buf));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-02-08 23:48:51 +01:00
|
|
|
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
for (i = 1; i <= steps; i++)
|
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if ((Piece->IsVisible(i)) && (Piece->GetStepShow() == i))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
const float* f = Piece->mModelWorld;
|
2014-04-14 05:43:31 +02:00
|
|
|
sprintf (buf, "1 %d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %s.DAT\r\n",
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece->mColorCode, f[12] * 25.0f, -f[14] * 25.0f, f[13] *25.0f, f[0], -f[8], f[4], -f[2], f[10], -f[6], f[1], -f[9], f[5], Piece->mPieceInfo->m_strName);
|
2012-03-23 00:44:56 +01:00
|
|
|
file.WriteBuffer(buf, strlen(buf));
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i != steps)
|
2012-03-23 00:44:56 +01:00
|
|
|
file.WriteBuffer("0 STEP\r\n", 8);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2012-03-23 00:44:56 +01:00
|
|
|
file.WriteBuffer("0\r\n", 3);
|
2012-02-08 23:48:51 +01:00
|
|
|
|
|
|
|
setlocale(LC_NUMERIC, OldLocale);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
FileSave(&file, false); // save me
|
2012-02-08 23:48:51 +01:00
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
file.Close();
|
|
|
|
|
|
|
|
SetModifiedFlag(false); // back to unmodified
|
|
|
|
|
|
|
|
// reset the title and change the document name
|
2013-08-09 06:57:18 +02:00
|
|
|
SetPathName(SaveFileName, true);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
return true; // success
|
|
|
|
}
|
|
|
|
|
|
|
|
// return true if ok to continue
|
|
|
|
bool Project::SaveModified()
|
|
|
|
{
|
|
|
|
if (!IsModified())
|
|
|
|
return true; // ok to continue
|
|
|
|
|
|
|
|
// get name/title of document
|
|
|
|
char name[LC_MAXPATH];
|
|
|
|
if (strlen(m_strPathName) == 0)
|
|
|
|
{
|
|
|
|
// get name based on caption
|
|
|
|
strcpy(name, m_strTitle);
|
|
|
|
if (strlen(name) == 0)
|
|
|
|
strcpy(name, "Untitled");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// get name based on file title of path name
|
|
|
|
char* p;
|
|
|
|
|
|
|
|
p = strrchr(m_strPathName, '\\');
|
|
|
|
if (!p)
|
|
|
|
p = strrchr(m_strPathName, '/');
|
|
|
|
|
|
|
|
if (p)
|
|
|
|
strcpy(name, ++p);
|
|
|
|
else
|
|
|
|
strcpy(name, m_strPathName);
|
|
|
|
}
|
|
|
|
|
|
|
|
char prompt[512];
|
|
|
|
sprintf(prompt, "Save changes to %s ?", name);
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
switch (gMainWindow->DoMessageBox(prompt, LC_MB_YESNOCANCEL))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
case LC_CANCEL:
|
|
|
|
return false; // don't continue
|
|
|
|
|
|
|
|
case LC_YES:
|
|
|
|
// If so, either Save or Update, as appropriate
|
2013-08-09 06:57:18 +02:00
|
|
|
if (!DoSave(m_strPathName))
|
|
|
|
return false;
|
2011-09-07 23:06:51 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_NO:
|
|
|
|
// If not saving changes, revert the document
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true; // keep going
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
void Project::SetModifiedFlag(bool Modified)
|
|
|
|
{
|
|
|
|
if (m_bModified != Modified)
|
|
|
|
{
|
|
|
|
m_bModified = Modified;
|
|
|
|
gMainWindow->UpdateModified(m_bModified);
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// File operations
|
|
|
|
|
|
|
|
bool Project::OnNewDocument()
|
|
|
|
{
|
|
|
|
SetTitle("Untitled");
|
|
|
|
DeleteContents(false);
|
|
|
|
memset(m_strPathName, 0, sizeof(m_strPathName)); // no path name yet
|
|
|
|
SetModifiedFlag(false); // make clean
|
|
|
|
LoadDefaults(true);
|
|
|
|
CheckPoint("");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Project::OpenProject(const char* FileName)
|
|
|
|
{
|
|
|
|
if (!SaveModified())
|
|
|
|
return false; // Leave the original one
|
|
|
|
|
|
|
|
bool WasModified = IsModified();
|
|
|
|
SetModifiedFlag(false); // Not dirty for open
|
|
|
|
|
|
|
|
if (!OnOpenDocument(FileName))
|
|
|
|
{
|
|
|
|
// Check if we corrupted the original document
|
|
|
|
if (!IsModified())
|
|
|
|
SetModifiedFlag(WasModified);
|
|
|
|
else
|
|
|
|
OnNewDocument();
|
|
|
|
|
|
|
|
return false; // Open failed
|
|
|
|
}
|
|
|
|
|
|
|
|
SetPathName(FileName, true);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Project::OnOpenDocument (const char* lpszPathName)
|
|
|
|
{
|
2012-03-23 00:44:56 +01:00
|
|
|
lcDiskFile file;
|
2011-09-07 23:06:51 +02:00
|
|
|
bool bSuccess = false;
|
|
|
|
|
|
|
|
if (!file.Open(lpszPathName, "rb"))
|
|
|
|
{
|
|
|
|
// MessageBox("Failed to open file.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char ext[4];
|
|
|
|
const char *ptr;
|
|
|
|
memset(ext, 0, 4);
|
|
|
|
ptr = strrchr(lpszPathName, '.');
|
|
|
|
if (ptr != NULL)
|
|
|
|
{
|
|
|
|
strncpy(ext, ptr+1, 3);
|
|
|
|
strlwr(ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool datfile = false;
|
|
|
|
bool mpdfile = false;
|
|
|
|
|
|
|
|
// Find out what file type we're loading.
|
|
|
|
if ((strcmp(ext, "dat") == 0) || (strcmp(ext, "ldr") == 0))
|
|
|
|
datfile = true;
|
|
|
|
else if (strcmp(ext, "mpd") == 0)
|
|
|
|
mpdfile = true;
|
|
|
|
|
|
|
|
// Delete the current project.
|
|
|
|
DeleteContents(false);
|
|
|
|
LoadDefaults(datfile || mpdfile);
|
|
|
|
SetModifiedFlag(true); // dirty during loading
|
|
|
|
|
|
|
|
if (file.GetLength() != 0)
|
|
|
|
{
|
2013-08-16 01:43:18 +02:00
|
|
|
lcArray<LC_FILEENTRY*> FileArray;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
// Unpack the MPD file.
|
|
|
|
if (mpdfile)
|
|
|
|
{
|
|
|
|
FileReadMPD(file, FileArray);
|
|
|
|
|
|
|
|
if (FileArray.GetSize() == 0)
|
|
|
|
{
|
|
|
|
file.Seek(0, SEEK_SET);
|
|
|
|
mpdfile = false;
|
|
|
|
datfile = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (datfile || mpdfile)
|
|
|
|
{
|
|
|
|
int ok = 0, step = 1;
|
2012-10-18 20:57:21 +02:00
|
|
|
lcMatrix44 mat = lcMatrix44Identity();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
if (mpdfile)
|
2012-10-18 20:57:21 +02:00
|
|
|
FileReadLDraw(&FileArray[0]->File, mat, &ok, 16, &step, FileArray);
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
2012-10-18 20:57:21 +02:00
|
|
|
FileReadLDraw(&file, mat, &ok, 16, &step, FileArray);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
m_nCurStep = step;
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2011-09-07 23:06:51 +02:00
|
|
|
UpdateSelection();
|
|
|
|
CalculateStep();
|
2012-12-11 00:30:28 +01:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
ZoomExtents(0, gMainWindow->GetViews().GetSize());
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
bSuccess = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Load a LeoCAD file.
|
|
|
|
bSuccess = FileLoad(&file, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up.
|
|
|
|
if (mpdfile)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < FileArray.GetSize(); i++)
|
|
|
|
delete FileArray[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
file.Close();
|
|
|
|
|
|
|
|
if (bSuccess == false)
|
|
|
|
{
|
|
|
|
// MessageBox("Failed to load.");
|
|
|
|
DeleteContents(false); // remove failed contents
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CheckPoint("");
|
|
|
|
|
|
|
|
SetModifiedFlag(false); // start off with unmodified
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
void Project::SetPathName(const char* PathName, bool bAddToMRU)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-01-28 02:05:23 +01:00
|
|
|
strcpy(m_strPathName, PathName);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
// always capture the complete file name including extension (if present)
|
2012-01-28 02:05:23 +01:00
|
|
|
const char* lpszTemp = PathName;
|
|
|
|
for (const char* lpsz = PathName; *lpsz != '\0'; lpsz++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
|
|
|
// remember last directory/drive separator
|
|
|
|
if (*lpsz == '\\' || *lpsz == '/' || *lpsz == ':')
|
|
|
|
lpszTemp = lpsz + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the document title based on path name
|
|
|
|
SetTitle(lpszTemp);
|
|
|
|
|
|
|
|
// add it to the file MRU list
|
|
|
|
if (bAddToMRU)
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->AddRecentFile(m_strPathName);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Undo/Redo support
|
|
|
|
|
|
|
|
// Save current state.
|
|
|
|
void Project::CheckPoint (const char* text)
|
|
|
|
{
|
|
|
|
LC_UNDOINFO* pTmp;
|
|
|
|
LC_UNDOINFO* pUndo = new LC_UNDOINFO;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
strcpy(pUndo->strText, text);
|
|
|
|
FileSave(&pUndo->file, true);
|
|
|
|
|
|
|
|
for (pTmp = m_pUndoList, i = 0; pTmp; pTmp = pTmp->pNext, i++)
|
|
|
|
if ((i == 30) && (pTmp->pNext != NULL))
|
|
|
|
{
|
|
|
|
delete pTmp->pNext;
|
|
|
|
pTmp->pNext = NULL;
|
|
|
|
m_bUndoOriginal = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
pUndo->pNext = m_pUndoList;
|
|
|
|
m_pUndoList = pUndo;
|
|
|
|
|
|
|
|
while (m_pRedoList)
|
|
|
|
{
|
|
|
|
pUndo = m_pRedoList;
|
|
|
|
m_pRedoList = m_pRedoList->pNext;
|
|
|
|
delete pUndo;
|
|
|
|
}
|
|
|
|
m_pRedoList = NULL;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateUndoRedo(m_pUndoList->pNext ? m_pUndoList->strText : NULL, NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Project rendering
|
|
|
|
|
|
|
|
// Only this function should be called.
|
2014-04-16 02:29:54 +02:00
|
|
|
void Project::Render(View* View, bool ToMemory)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-16 02:29:54 +02:00
|
|
|
View->mContext->SetDefaultState();
|
|
|
|
glViewport(0, 0, View->mWidth, View->mHeight);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
RenderBackground(View);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
RenderScenePieces(View, !ToMemory);
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (!ToMemory)
|
|
|
|
{
|
2014-04-16 02:29:54 +02:00
|
|
|
RenderSceneObjects(View);
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
RenderViewports(View);
|
2011-09-20 03:26:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
void Project::RenderBackground(View* View)
|
2011-09-20 03:26:31 +02:00
|
|
|
{
|
2014-04-16 02:29:54 +02:00
|
|
|
lcContext* Context = View->mContext;
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (mProperties.mBackgroundType == LC_BACKGROUND_SOLID)
|
2011-09-20 03:26:31 +02:00
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
glClearColor(mProperties.mBackgroundSolidColor[0], mProperties.mBackgroundSolidColor[1], mProperties.mBackgroundSolidColor[2], 0.0f);
|
2011-09-20 03:26:31 +02:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2011-09-07 23:06:51 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-09-20 03:26:31 +02:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2011-09-20 03:26:31 +02:00
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDisable(GL_LIGHTING);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
float ViewWidth = (float)View->mWidth;
|
|
|
|
float ViewHeight = (float)View->mHeight;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
Context->SetProjectionMatrix(lcMatrix44Ortho(0.0f, ViewWidth, 0.0f, ViewHeight, -1.0f, 1.0f));
|
|
|
|
Context->SetWorldViewMatrix(lcMatrix44Translation(lcVector3(0.375f, 0.375f, 0.0f)));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (mProperties.mBackgroundType == LC_BACKGROUND_GRADIENT)
|
2011-09-20 03:26:31 +02:00
|
|
|
{
|
|
|
|
glShadeModel(GL_SMOOTH);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
const lcVector3& Color1 = mProperties.mBackgroundGradientColor1;
|
|
|
|
const lcVector3& Color2 = mProperties.mBackgroundGradientColor2;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
float Verts[] =
|
|
|
|
{
|
|
|
|
ViewWidth, ViewHeight, Color1[0], Color1[1], Color1[2], 1.0f,
|
|
|
|
0.0f, ViewHeight, Color1[0], Color1[1], Color1[2], 1.0f,
|
|
|
|
0.0f, 0.0f, Color2[0], Color2[1], Color2[2], 1.0f,
|
|
|
|
ViewWidth, 0.0f, Color2[0], Color2[1], Color2[2], 1.0f
|
|
|
|
};
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
glVertexPointer(2, GL_FLOAT, 6 * sizeof(float), Verts);
|
|
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glColorPointer(4, GL_FLOAT, 6 * sizeof(float), Verts + 2);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
|
|
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
|
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
}
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE)
|
2011-09-20 03:26:31 +02:00
|
|
|
{
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
2012-10-12 20:21:45 +02:00
|
|
|
glBindTexture(GL_TEXTURE_2D, m_pBackground->mTexture);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
float TileWidth = 1.0f, TileHeight = 1.0f;
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (mProperties.mBackgroundImageTile)
|
2011-09-20 03:26:31 +02:00
|
|
|
{
|
2014-04-16 02:29:54 +02:00
|
|
|
TileWidth = ViewWidth / m_pBackground->mWidth;
|
|
|
|
TileHeight = ViewHeight / m_pBackground->mHeight;
|
2011-09-20 03:26:31 +02:00
|
|
|
}
|
|
|
|
|
2014-04-16 02:29:54 +02:00
|
|
|
float Verts[] =
|
|
|
|
{
|
|
|
|
0.0f, ViewHeight, 0.0f, 0.0f,
|
|
|
|
ViewWidth, ViewHeight, TileWidth, 0.0f,
|
|
|
|
ViewWidth, 0.0f, TileWidth, TileHeight,
|
|
|
|
0.0f, 0.0f, 0.0f, TileHeight
|
|
|
|
};
|
|
|
|
|
|
|
|
glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), Verts);
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), Verts + 2);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
|
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
}
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthMask(GL_TRUE);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
void Project::RenderScenePieces(View* view, bool DrawInterface)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
const lcPreferences& Preferences = lcGetPreferences();
|
2014-05-03 03:22:24 +02:00
|
|
|
lcContext* Context = view->mContext;
|
2014-02-10 01:13:41 +01:00
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
Context->SetProjectionMatrix(view->GetProjectionMatrix());
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mLightingMode != LC_LIGHTING_FLAT)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
|
|
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
|
|
|
GLfloat mat_translucent[] = { (GLfloat)0.8, (GLfloat)0.8, (GLfloat)0.8, (GLfloat)1.0 };
|
|
|
|
GLfloat mat_opaque[] = { (GLfloat)0.8, (GLfloat)0.8, (GLfloat)0.8, (GLfloat)1.0 };
|
|
|
|
GLfloat medium_shininess[] = { (GLfloat)64.0 };
|
|
|
|
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, medium_shininess);
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_opaque);
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_translucent);
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lcVector4(mProperties.mAmbientColor, 1.0f));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-04-09 00:34:50 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
mLights[LightIdx]->Setup(LightIdx);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
}
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (mProperties.mFogEnabled)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
|
|
|
glFogi(GL_FOG_MODE, GL_EXP);
|
2014-02-10 01:13:41 +01:00
|
|
|
glFogf(GL_FOG_DENSITY, mProperties.mFogDensity);
|
|
|
|
glFogfv(GL_FOG_COLOR, lcVector4(mProperties.mFogColor, 1.0f));
|
2012-01-28 02:05:23 +01:00
|
|
|
glEnable(GL_FOG);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
// if (m_nScene & LC_SCENE_FLOOR)
|
|
|
|
// m_pTerrain->Render(view->mCamera, AspectRatio);
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
lcArray<lcRenderMesh> OpaqueMeshes(mPieces.GetSize());
|
|
|
|
lcArray<lcRenderMesh> TranslucentMeshes;
|
2014-02-16 08:23:55 +01:00
|
|
|
const lcMatrix44& ViewMatrix = view->mCamera->mWorldView;
|
2014-04-20 03:50:41 +02:00
|
|
|
|
|
|
|
Context->SetLineWidth(Preferences.mLineWidth);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2012-01-28 02:05:23 +01:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if (!Piece->IsVisible(m_nCurStep))
|
2012-01-28 02:05:23 +01:00
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
PieceInfo* Info = Piece->mPieceInfo;
|
2014-04-23 16:53:43 +02:00
|
|
|
bool Focused, Selected;
|
2014-04-20 03:50:41 +02:00
|
|
|
|
|
|
|
if (DrawInterface)
|
|
|
|
{
|
2014-04-23 16:53:43 +02:00
|
|
|
Focused = Piece->IsFocused();
|
|
|
|
Selected = Piece->IsSelected();
|
2014-04-20 03:50:41 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-04-23 16:53:43 +02:00
|
|
|
Focused = false;
|
|
|
|
Selected = false;
|
2014-04-20 03:50:41 +02:00
|
|
|
}
|
|
|
|
|
2014-04-23 16:53:43 +02:00
|
|
|
Info->AddRenderMeshes(ViewMatrix, &Piece->mModelWorld, Piece->mColorIndex, Focused, Selected, OpaqueMeshes, TranslucentMeshes);
|
2012-05-17 01:48:16 +02:00
|
|
|
}
|
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
OpaqueMeshes.Sort(lcOpaqueRenderMeshCompare);
|
|
|
|
Context->DrawOpaqueMeshes(ViewMatrix, OpaqueMeshes);
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
TranslucentMeshes.Sort(lcTranslucentRenderMeshCompare);
|
|
|
|
Context->DrawTranslucentMeshes(ViewMatrix, TranslucentMeshes);
|
|
|
|
|
|
|
|
Context->UnbindMesh(); // context remove
|
|
|
|
|
|
|
|
if (Preferences.mLightingMode != LC_LIGHTING_FLAT)
|
2012-05-17 01:48:16 +02:00
|
|
|
{
|
2014-04-20 03:50:41 +02:00
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
}
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
if (mProperties.mFogEnabled)
|
|
|
|
glDisable(GL_FOG);
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
if (DrawInterface)
|
|
|
|
{
|
|
|
|
Context->SetLineWidth(2.0f * Preferences.mLineWidth);
|
|
|
|
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2012-05-17 01:48:16 +02:00
|
|
|
{
|
2014-04-20 03:50:41 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
if (!Piece->IsVisible(m_nCurStep) || !Piece->IsSelected())
|
|
|
|
continue;
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
PieceInfo* PieceInfo = Piece->mPieceInfo;
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
lcVector3 Min(PieceInfo->m_fDimensions[3], PieceInfo->m_fDimensions[4], PieceInfo->m_fDimensions[5]);
|
|
|
|
lcVector3 Max(PieceInfo->m_fDimensions[0], PieceInfo->m_fDimensions[1], PieceInfo->m_fDimensions[2]);
|
|
|
|
lcVector3 Edge((Max - Min) * 0.33f);
|
|
|
|
|
|
|
|
float Verts[48][3] =
|
2012-05-17 01:48:16 +02:00
|
|
|
{
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Max[0], Max[1], Max[2] }, { Max[0] - Edge[0], Max[1], Max[2] },
|
|
|
|
{ Max[0], Max[1], Max[2] }, { Max[0], Max[1] - Edge[1], Max[2] },
|
|
|
|
{ Max[0], Max[1], Max[2] }, { Max[0], Max[1], Max[2] - Edge[2] },
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Min[0], Max[1], Max[2] }, { Min[0] + Edge[0], Max[1], Max[2] },
|
|
|
|
{ Min[0], Max[1], Max[2] }, { Min[0], Max[1] - Edge[1], Max[2] },
|
|
|
|
{ Min[0], Max[1], Max[2] }, { Min[0], Max[1], Max[2] - Edge[2] },
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Max[0], Min[1], Max[2] }, { Max[0] - Edge[0], Min[1], Max[2] },
|
|
|
|
{ Max[0], Min[1], Max[2] }, { Max[0], Min[1] + Edge[1], Max[2] },
|
|
|
|
{ Max[0], Min[1], Max[2] }, { Max[0], Min[1], Max[2] - Edge[2] },
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Min[0], Min[1], Max[2] }, { Min[0] + Edge[0], Min[1], Max[2] },
|
|
|
|
{ Min[0], Min[1], Max[2] }, { Min[0], Min[1] + Edge[1], Max[2] },
|
|
|
|
{ Min[0], Min[1], Max[2] }, { Min[0], Min[1], Max[2] - Edge[2] },
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Max[0], Max[1], Min[2] }, { Max[0] - Edge[0], Max[1], Min[2] },
|
|
|
|
{ Max[0], Max[1], Min[2] }, { Max[0], Max[1] - Edge[1], Min[2] },
|
|
|
|
{ Max[0], Max[1], Min[2] }, { Max[0], Max[1], Min[2] + Edge[2] },
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Min[0], Max[1], Min[2] }, { Min[0] + Edge[0], Max[1], Min[2] },
|
|
|
|
{ Min[0], Max[1], Min[2] }, { Min[0], Max[1] - Edge[1], Min[2] },
|
|
|
|
{ Min[0], Max[1], Min[2] }, { Min[0], Max[1], Min[2] + Edge[2] },
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Max[0], Min[1], Min[2] }, { Max[0] - Edge[0], Min[1], Min[2] },
|
|
|
|
{ Max[0], Min[1], Min[2] }, { Max[0], Min[1] + Edge[1], Min[2] },
|
|
|
|
{ Max[0], Min[1], Min[2] }, { Max[0], Min[1], Min[2] + Edge[2] },
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
{ Min[0], Min[1], Min[2] }, { Min[0] + Edge[0], Min[1], Min[2] },
|
|
|
|
{ Min[0], Min[1], Min[2] }, { Min[0], Min[1] + Edge[1], Min[2] },
|
|
|
|
{ Min[0], Min[1], Min[2] }, { Min[0], Min[1], Min[2] + Edge[2] },
|
|
|
|
};
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
Context->SetWorldViewMatrix(lcMul(Piece->mModelWorld, ViewMatrix));
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
if (Piece->IsFocused())
|
|
|
|
lcSetColorFocused();
|
|
|
|
else
|
|
|
|
lcSetColorSelected();
|
2012-05-17 01:48:16 +02:00
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
glVertexPointer(3, GL_FLOAT, 0, Verts);
|
|
|
|
glDrawArrays(GL_LINES, 0, 48);
|
2012-05-17 01:48:16 +02:00
|
|
|
}
|
|
|
|
|
2014-04-20 03:50:41 +02:00
|
|
|
Context->SetLineWidth(Preferences.mLineWidth); // context remove
|
2012-05-17 01:48:16 +02:00
|
|
|
}
|
2012-01-28 02:05:23 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
void Project::RenderSceneObjects(View* view)
|
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
const lcPreferences& Preferences = lcGetPreferences();
|
2014-02-16 08:23:55 +01:00
|
|
|
const lcMatrix44& ViewMatrix = view->mCamera->mWorldView;
|
2014-04-14 05:20:16 +02:00
|
|
|
lcContext* Context = view->mContext;
|
2014-02-10 01:13:41 +01:00
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
Context->SetProjectionMatrix(view->GetProjectionMatrix());
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
#ifdef LC_DEBUG
|
2012-01-28 02:05:23 +01:00
|
|
|
RenderDebugPrimitives();
|
2011-09-07 23:06:51 +02:00
|
|
|
#endif
|
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
// Draw cameras & lights
|
2014-05-23 02:02:21 +02:00
|
|
|
if (gMainWindow->GetTool() == LC_TOOL_INSERT || mDropPiece)
|
2012-01-28 02:05:23 +01:00
|
|
|
{
|
2014-02-16 08:23:55 +01:00
|
|
|
lcVector3 Position;
|
|
|
|
lcVector4 Rotation;
|
2014-05-03 18:59:57 +02:00
|
|
|
GetPieceInsertPosition(view, Position, Rotation);
|
2013-08-09 06:57:18 +02:00
|
|
|
PieceInfo* PreviewPiece = mDropPiece ? mDropPiece : m_pCurPiece;
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-02-16 08:23:55 +01:00
|
|
|
lcMatrix44 WorldMatrix = lcMatrix44FromAxisAngle(lcVector3(Rotation[0], Rotation[1], Rotation[2]), Rotation[3] * LC_DTOR);
|
|
|
|
WorldMatrix.SetTranslation(Position);
|
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
Context->SetWorldViewMatrix(lcMul(WorldMatrix, ViewMatrix));
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-04-14 05:20:16 +02:00
|
|
|
Context->SetLineWidth(2.0f * Preferences.mLineWidth);
|
2013-08-09 06:57:18 +02:00
|
|
|
PreviewPiece->RenderPiece(gMainWindow->mColorIndex);
|
2012-01-28 02:05:23 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mLightingMode != LC_LIGHTING_FLAT)
|
2012-01-28 02:05:23 +01:00
|
|
|
glDisable (GL_LIGHTING);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
2012-01-28 02:05:23 +01:00
|
|
|
{
|
2012-08-22 03:13:32 +02:00
|
|
|
Camera* pCamera = mCameras[CameraIdx];
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
if ((pCamera == view->mCamera) || !pCamera->IsVisible())
|
2012-01-28 02:05:23 +01:00
|
|
|
continue;
|
2012-08-20 06:05:56 +02:00
|
|
|
|
2014-04-14 05:20:16 +02:00
|
|
|
pCamera->Render(view);
|
2012-01-28 02:05:23 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-09 00:34:50 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (mLights[LightIdx]->IsVisible())
|
2014-04-14 05:20:16 +02:00
|
|
|
mLights[LightIdx]->Render(view);
|
|
|
|
|
|
|
|
Context->SetLineWidth(Preferences.mLineWidth); // context remove
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mDrawGridStuds || Preferences.mDrawGridLines)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-03 03:22:24 +02:00
|
|
|
Context->SetWorldViewMatrix(ViewMatrix);
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
const int Spacing = lcMax(Preferences.mGridLineSpacing, 1);
|
2013-09-01 23:45:19 +02:00
|
|
|
int MinX = 0, MaxX = 0, MinY = 0, MaxY = 0;
|
|
|
|
|
2014-05-23 02:02:21 +02:00
|
|
|
if (!mPieces.IsEmpty() || (gMainWindow->GetTool() == LC_TOOL_INSERT || mDropPiece))
|
2013-09-01 23:45:19 +02:00
|
|
|
{
|
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
}
|
2013-09-01 23:45:19 +02:00
|
|
|
|
2014-05-23 02:02:21 +02:00
|
|
|
if (gMainWindow->GetTool() == LC_TOOL_INSERT || mDropPiece)
|
2013-09-02 00:19:53 +02:00
|
|
|
{
|
|
|
|
lcVector3 Position;
|
|
|
|
lcVector4 Rotation;
|
2014-05-03 18:59:57 +02:00
|
|
|
GetPieceInsertPosition(view, Position, Rotation);
|
2013-09-02 00:19:53 +02:00
|
|
|
|
2013-09-02 00:25:34 +02:00
|
|
|
PieceInfo* PreviewPiece = mDropPiece ? mDropPiece : m_pCurPiece;
|
|
|
|
|
2013-09-02 00:19:53 +02:00
|
|
|
lcVector3 Points[8] =
|
|
|
|
{
|
2013-09-02 00:25:34 +02:00
|
|
|
lcVector3(PreviewPiece->m_fDimensions[0],PreviewPiece->m_fDimensions[1], PreviewPiece->m_fDimensions[5]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[3],PreviewPiece->m_fDimensions[1], PreviewPiece->m_fDimensions[5]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[0],PreviewPiece->m_fDimensions[1], PreviewPiece->m_fDimensions[2]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[3],PreviewPiece->m_fDimensions[4], PreviewPiece->m_fDimensions[5]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[3],PreviewPiece->m_fDimensions[4], PreviewPiece->m_fDimensions[2]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[0],PreviewPiece->m_fDimensions[4], PreviewPiece->m_fDimensions[2]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[0],PreviewPiece->m_fDimensions[4], PreviewPiece->m_fDimensions[5]),
|
|
|
|
lcVector3(PreviewPiece->m_fDimensions[3],PreviewPiece->m_fDimensions[1], PreviewPiece->m_fDimensions[2])
|
2013-09-02 00:19:53 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
lcMatrix44 ModelWorld = lcMatrix44FromAxisAngle(lcVector3(Rotation[0], Rotation[1], Rotation[2]), Rotation[3] * LC_DTOR);
|
|
|
|
ModelWorld.SetTranslation(Position);
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
lcVector3 Point = lcMul31(Points[i], ModelWorld);
|
|
|
|
|
|
|
|
if (Point[0] < bs[0]) bs[0] = Point[0];
|
|
|
|
if (Point[1] < bs[1]) bs[1] = Point[1];
|
|
|
|
if (Point[2] < bs[2]) bs[2] = Point[2];
|
|
|
|
if (Point[0] > bs[3]) bs[3] = Point[0];
|
|
|
|
if (Point[1] > bs[4]) bs[4] = Point[1];
|
|
|
|
if (Point[2] > bs[5]) bs[5] = Point[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-01 23:45:19 +02:00
|
|
|
MinX = (int)(floorf(bs[0] / (0.8f * Spacing))) - 1;
|
|
|
|
MinY = (int)(floorf(bs[1] / (0.8f * Spacing))) - 1;
|
|
|
|
MaxX = (int)(ceilf(bs[3] / (0.8f * Spacing))) + 1;
|
|
|
|
MaxY = (int)(ceilf(bs[4] / (0.8f * Spacing))) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
MinX = lcMin(MinX, -2);
|
|
|
|
MinY = lcMin(MinY, -2);
|
|
|
|
MaxX = lcMax(MaxX, 2);
|
|
|
|
MaxY = lcMax(MaxY, 2);
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mDrawGridStuds)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2013-09-01 23:45:19 +02:00
|
|
|
float Left = MinX * 0.8f * Spacing;
|
|
|
|
float Right = MaxX * 0.8f * Spacing;
|
|
|
|
float Top = MinY * 0.8f * Spacing;
|
|
|
|
float Bottom = MaxY * 0.8f * Spacing;
|
2013-08-31 23:58:47 +02:00
|
|
|
float Z = 0;
|
2013-09-01 23:45:19 +02:00
|
|
|
float U = (MaxX - MinX) * Spacing;
|
|
|
|
float V = (MaxY - MinY) * Spacing;
|
2013-08-31 23:58:47 +02:00
|
|
|
|
|
|
|
float Verts[4 * 5];
|
|
|
|
float* CurVert = Verts;
|
|
|
|
|
|
|
|
*CurVert++ = Left;
|
|
|
|
*CurVert++ = Top;
|
|
|
|
*CurVert++ = Z;
|
|
|
|
*CurVert++ = 0.0f;
|
|
|
|
*CurVert++ = V;
|
|
|
|
|
|
|
|
*CurVert++ = Left;
|
|
|
|
*CurVert++ = Bottom;
|
|
|
|
*CurVert++ = Z;
|
|
|
|
*CurVert++ = 0.0f;
|
|
|
|
*CurVert++ = 0.0f;
|
|
|
|
|
|
|
|
*CurVert++ = Right;
|
|
|
|
*CurVert++ = Bottom;
|
|
|
|
*CurVert++ = Z;
|
|
|
|
*CurVert++ = U;
|
|
|
|
*CurVert++ = 0.0f;
|
|
|
|
|
|
|
|
*CurVert++ = Right;
|
|
|
|
*CurVert++ = Top;
|
|
|
|
*CurVert++ = Z;
|
|
|
|
*CurVert++ = U;
|
|
|
|
*CurVert++ = V;
|
|
|
|
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mGridTexture->mTexture);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
glColor4fv(lcVector4FromColor(Preferences.mGridStudColor));
|
2013-08-31 23:58:47 +02:00
|
|
|
|
|
|
|
glVertexPointer(3, GL_FLOAT, 5 * sizeof(float), Verts);
|
|
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glTexCoordPointer(2, GL_FLOAT, 5 * sizeof(float), Verts + 3);
|
|
|
|
|
|
|
|
glDrawArrays(GL_QUADS, 0, 4);
|
|
|
|
|
|
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
}
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mDrawGridLines)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-02-10 01:13:41 +01:00
|
|
|
glColor4fv(lcVector4FromColor(Preferences.mGridLineColor));
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2013-09-01 23:45:19 +02:00
|
|
|
int NumVerts = 2 * (MaxX - MinX + MaxY - MinY + 2);
|
2013-08-31 23:58:47 +02:00
|
|
|
float* Verts = (float*)malloc(NumVerts * sizeof(float[3]));
|
2013-09-01 23:45:19 +02:00
|
|
|
float* Vert = Verts;
|
|
|
|
float LineSpacing = Spacing * 0.8f;
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2013-09-01 23:45:19 +02:00
|
|
|
for (int Step = MinX; Step < MaxX + 1; Step++)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2013-09-01 23:45:19 +02:00
|
|
|
*Vert++ = Step * LineSpacing;
|
|
|
|
*Vert++ = MinY * LineSpacing;
|
|
|
|
*Vert++ = 0.0f;
|
|
|
|
*Vert++ = Step * LineSpacing;
|
|
|
|
*Vert++ = MaxY * LineSpacing;
|
|
|
|
*Vert++ = 0.0f;
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
2013-09-01 23:45:19 +02:00
|
|
|
|
|
|
|
for (int Step = MinY; Step < MaxY + 1; Step++)
|
|
|
|
{
|
|
|
|
*Vert++ = MinX * LineSpacing;
|
|
|
|
*Vert++ = Step * LineSpacing;
|
|
|
|
*Vert++ = 0.0f;
|
|
|
|
*Vert++ = MaxX * LineSpacing;
|
|
|
|
*Vert++ = Step * LineSpacing;
|
|
|
|
*Vert++ = 0.0f;
|
|
|
|
}
|
|
|
|
|
2013-08-31 23:58:47 +02:00
|
|
|
glVertexPointer(3, GL_FLOAT, 0, Verts);
|
|
|
|
glDrawArrays(GL_LINES, 0, NumVerts);
|
|
|
|
free(Verts);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-10 01:13:41 +01:00
|
|
|
if (Preferences.mDrawAxes)
|
2012-01-28 02:05:23 +01:00
|
|
|
{
|
|
|
|
// glClear(GL_DEPTH_BUFFER_BIT);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-06-16 02:17:52 +02:00
|
|
|
lcMatrix44 Mats[3];
|
2012-08-20 06:05:56 +02:00
|
|
|
Mats[0] = view->mCamera->mWorldView;
|
2012-06-16 02:17:52 +02:00
|
|
|
Mats[0].SetTranslation(lcVector3(0, 0, 0));
|
|
|
|
Mats[1] = lcMul(lcMatrix44(lcVector4(0, 1, 0, 0), lcVector4(1, 0, 0, 0), lcVector4(0, 0, 1, 0), lcVector4(0, 0, 0, 1)), Mats[0]);
|
|
|
|
Mats[2] = lcMul(lcMatrix44(lcVector4(0, 0, 1, 0), lcVector4(0, 1, 0, 0), lcVector4(1, 0, 0, 0), lcVector4(0, 0, 0, 1)), Mats[0]);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-01-06 20:24:25 +01:00
|
|
|
lcVector3 pts[3] =
|
2012-06-16 02:17:52 +02:00
|
|
|
{
|
|
|
|
lcMul30(lcVector3(20, 0, 0), Mats[0]),
|
|
|
|
lcMul30(lcVector3(0, 20, 0), Mats[0]),
|
|
|
|
lcMul30(lcVector3(0, 0, 20), Mats[0]),
|
|
|
|
};
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-03 03:22:24 +02:00
|
|
|
Context->SetProjectionMatrix(lcMatrix44Ortho(0, view->mWidth, 0, view->mHeight, -50, 50));
|
|
|
|
Context->SetWorldViewMatrix(lcMatrix44Translation(lcVector3(25.375f, 25.375f, 0.0f)));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
// Draw the arrows.
|
2012-09-10 01:42:57 +02:00
|
|
|
lcVector3 Verts[11];
|
|
|
|
Verts[0] = lcVector3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, Verts);
|
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
switch (i)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
glColor4f(0.8f, 0.0f, 0.0f, 1.0f);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
glColor4f(0.0f, 0.8f, 0.0f, 1.0f);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
glColor4f(0.0f, 0.0f, 0.8f, 1.0f);
|
|
|
|
break;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-09-10 01:42:57 +02:00
|
|
|
Verts[1] = pts[i];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
for (int j = 0; j < 9; j++)
|
2012-09-10 01:42:57 +02:00
|
|
|
Verts[j+2] = lcMul30(lcVector3(12.0f, cosf(LC_2PI * j / 8) * 3.0f, sinf(LC_2PI * j / 8) * 3.0f), Mats[i]);
|
|
|
|
|
|
|
|
glDrawArrays(GL_LINES, 0, 2);
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 1, 10);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2012-01-28 02:05:23 +01:00
|
|
|
// Draw the text.
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
m_pScreenFont->MakeCurrent();
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2013-09-08 07:54:56 +02:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
2012-01-28 02:05:23 +01:00
|
|
|
|
|
|
|
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
m_pScreenFont->PrintText(pts[0][0], pts[0][1], 40.0f, "X");
|
|
|
|
m_pScreenFont->PrintText(pts[1][0], pts[1][1], 40.0f, "Y");
|
|
|
|
m_pScreenFont->PrintText(pts[2][0], pts[2][1], 40.0f, "Z");
|
|
|
|
|
2013-09-08 07:54:56 +02:00
|
|
|
glDisable(GL_BLEND);
|
2012-01-28 02:05:23 +01:00
|
|
|
glDisable(GL_TEXTURE_2D);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::RenderViewports(View* view)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-03 03:22:24 +02:00
|
|
|
lcContext* Context = view->mContext;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Context->SetProjectionMatrix(lcMatrix44Ortho(0.0f, view->mWidth, 0.0f, view->mHeight, -1.0f, 1.0f));
|
|
|
|
Context->SetWorldViewMatrix(lcMatrix44Translation(lcVector3(0.375f, 0.375f, 0.0f)));
|
2013-04-10 02:52:06 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDisable(GL_LIGHTING);
|
2013-04-10 02:52:06 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Draw camera name
|
|
|
|
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
m_pScreenFont->MakeCurrent();
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
2013-04-10 02:52:06 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
String str(view->mCamera->GetName());
|
|
|
|
if (str.GetLength() > 0)
|
|
|
|
m_pScreenFont->PrintText(3.0f, (float)view->mHeight - 1.0f - 6.0f, 0.0f, str);
|
2013-04-10 02:52:06 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
2012-01-28 02:05:23 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
glDepthMask(GL_TRUE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Initialize OpenGL
|
|
|
|
void Project::RenderInitialize()
|
|
|
|
{
|
|
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
glPolygonOffset(0.5f, 0.1f);
|
2014-05-03 03:22:24 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
glDepthMask(GL_TRUE);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Load font
|
|
|
|
if (!m_pScreenFont->IsLoaded())
|
|
|
|
m_pScreenFont->Initialize();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// if (m_nScene & LC_SCENE_FLOOR)
|
|
|
|
// m_pTerrain->LoadTexture();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE)
|
|
|
|
if (!m_pBackground->Load(mProperties.mBackgroundImage.Buffer(), LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
mProperties.mBackgroundType = LC_BACKGROUND_SOLID;
|
|
|
|
// AfxMessageBox ("Could not load background");
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!mGridTexture->mTexture)
|
|
|
|
{
|
|
|
|
const int NumLevels = 9;
|
|
|
|
Image GridImages[NumLevels];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int ImageLevel = 0; ImageLevel < NumLevels; ImageLevel++)
|
|
|
|
{
|
|
|
|
Image& GridImage = GridImages[ImageLevel];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const int GridSize = 256 >> ImageLevel;
|
|
|
|
const float Radius1 = (80 >> ImageLevel) * (80 >> ImageLevel);
|
|
|
|
const float Radius2 = (72 >> ImageLevel) * (72 >> ImageLevel);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GridImage.Allocate(GridSize, GridSize, LC_PIXEL_FORMAT_A8);
|
|
|
|
lcuint8* BlurBuffer = new lcuint8[GridSize * GridSize];
|
2012-09-10 01:42:57 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int y = 0; y < GridSize; y++)
|
2012-09-10 01:42:57 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcuint8* Pixel = GridImage.mData + y * GridSize;
|
|
|
|
memset(Pixel, 0, GridSize);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const float y2 = (y - GridSize / 2) * (y - GridSize / 2);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Radius1 <= y2)
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Radius2 <= y2)
|
|
|
|
{
|
|
|
|
int x1 = sqrtf(Radius1 - y2);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int x = GridSize / 2 - x1; x < GridSize / 2 + x1; x++)
|
|
|
|
Pixel[x] = 255;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int x1 = sqrtf(Radius1 - y2);
|
|
|
|
int x2 = sqrtf(Radius2 - y2);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int x = GridSize / 2 - x1; x < GridSize / 2 - x2; x++)
|
|
|
|
Pixel[x] = 255;
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int x = GridSize / 2 + x2; x < GridSize / 2 + x1; x++)
|
|
|
|
Pixel[x] = 255;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int y = 0; y < GridSize - 1; y++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int x = 0; x < GridSize - 1; x++)
|
2012-08-09 00:11:23 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcuint8 a = GridImage.mData[x + y * GridSize];
|
|
|
|
lcuint8 b = GridImage.mData[x + 1 + y * GridSize];
|
|
|
|
lcuint8 c = GridImage.mData[x + (y + 1) * GridSize];
|
|
|
|
lcuint8 d = GridImage.mData[x + 1 + (y + 1) * GridSize];
|
|
|
|
BlurBuffer[x + y * GridSize] = (a + b + c + d) / 4;
|
2012-08-09 00:11:23 +02:00
|
|
|
}
|
2013-01-11 22:02:55 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int x = GridSize - 1;
|
|
|
|
lcuint8 a = GridImage.mData[x + y * GridSize];
|
|
|
|
lcuint8 c = GridImage.mData[x + (y + 1) * GridSize];
|
|
|
|
BlurBuffer[x + y * GridSize] = (a + c) / 2;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int y = GridSize - 1;
|
|
|
|
for (int x = 0; x < GridSize - 1; x++)
|
2013-12-15 22:51:22 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcuint8 a = GridImage.mData[x + y * GridSize];
|
|
|
|
lcuint8 b = GridImage.mData[x + 1 + y * GridSize];
|
|
|
|
BlurBuffer[x + y * GridSize] = (a + b) / 2;
|
2013-12-15 22:51:22 +01:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int x = GridSize - 1;
|
|
|
|
BlurBuffer[x + y * GridSize] = GridImage.mData[x + y * GridSize];
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
memcpy(GridImage.mData, BlurBuffer, GridSize * GridSize);
|
|
|
|
delete[] BlurBuffer;
|
|
|
|
}
|
2012-08-10 23:51:07 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
mGridTexture->Load(GridImages, NumLevels, LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_MIPMAPS | LC_TEXTURE_ANISOTROPIC);
|
|
|
|
}
|
|
|
|
}
|
2012-08-10 23:51:07 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Project functions
|
2012-08-10 23:51:07 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::CalculateStep()
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
if (!Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->SetSelected(false);
|
|
|
|
else
|
|
|
|
SelectGroup(Piece->GetTopGroup(), true);
|
|
|
|
}
|
|
|
|
}
|
2012-08-10 23:51:07 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
mCameras[CameraIdx]->UpdatePosition(m_nCurStep);
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
mLights[LightIdx]->UpdatePosition(m_nCurStep);
|
|
|
|
}
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::RemoveSelectedObjects()
|
|
|
|
{
|
|
|
|
bool RemovedPiece = false;
|
|
|
|
bool RemovedCamera = false;
|
|
|
|
bool RemovedLight = false;
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); )
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
RemovedPiece = true;
|
|
|
|
mPieces.Remove(Piece);
|
|
|
|
delete Piece;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
PieceIdx++;
|
|
|
|
}
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); )
|
|
|
|
{
|
|
|
|
Camera* Camera = mCameras[CameraIdx];
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera->IsSelected())
|
|
|
|
{
|
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
|
|
|
|
{
|
|
|
|
View* View = Views[ViewIdx];
|
2012-08-02 23:14:26 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera == View->mCamera)
|
|
|
|
View->SetCamera(Camera, true);
|
2012-07-31 07:27:40 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RemovedCamera = true;
|
|
|
|
mCameras.RemoveIndex(CameraIdx);
|
|
|
|
delete Camera;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
CameraIdx++;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (RemovedCamera)
|
|
|
|
gMainWindow->UpdateCameraMenu();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); )
|
|
|
|
{
|
|
|
|
Light* Light = mLights[LightIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Light->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
RemovedLight = true;
|
|
|
|
mLights.RemoveIndex(LightIdx);
|
|
|
|
delete Light;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else
|
|
|
|
LightIdx++;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RemoveEmptyGroups();
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return RemovedPiece || RemovedCamera || RemovedLight;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateSelection()
|
|
|
|
{
|
|
|
|
unsigned long flags = 0;
|
|
|
|
int SelectedCount = 0;
|
|
|
|
Object* Focus = NULL;
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mPieces.IsEmpty())
|
|
|
|
flags |= LC_SEL_NO_PIECES;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Group* pGroup = NULL;
|
|
|
|
bool first = true;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
SelectedCount++;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused())
|
|
|
|
Focus = Piece;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (flags & LC_SEL_PIECE)
|
|
|
|
flags |= LC_SEL_MULTIPLE;
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
2014-05-18 01:03:05 +02:00
|
|
|
flags |= LC_SEL_PIECE;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->GetGroup() != NULL)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
flags |= LC_SEL_GROUP;
|
|
|
|
if (Piece->IsFocused())
|
|
|
|
flags |= LC_SEL_FOCUSGROUP;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
pGroup = Piece->GetGroup();
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pGroup != Piece->GetGroup())
|
|
|
|
flags |= LC_SEL_CANGROUP;
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pGroup == NULL)
|
|
|
|
flags |= LC_SEL_CANGROUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
flags |= LC_SEL_UNSELECTED;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsHidden())
|
|
|
|
flags |= LC_SEL_HIDDEN;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* pCamera = mCameras[CameraIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pCamera->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
flags |= LC_SEL_CAMERA;
|
|
|
|
SelectedCount++;
|
2013-01-11 22:02:55 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pCamera->IsFocused())
|
|
|
|
Focus = pCamera;
|
2012-08-09 00:11:23 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
{
|
|
|
|
Light* pLight = mLights[LightIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pLight->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
flags |= LC_SEL_LIGHT;
|
|
|
|
SelectedCount++;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pLight->IsFocused())
|
|
|
|
Focus = pLight;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateSelectedObjects(flags, SelectedCount, Focus);
|
|
|
|
}
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::CheckAutoSave()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
m_nSaveTimer += 5;
|
|
|
|
if (m_nAutosave & LC_AUTOSAVE_FLAG)
|
|
|
|
{
|
|
|
|
// int nInterval;
|
|
|
|
// nInterval = m_nAutosave & ~LC_AUTOSAVE_FLAG;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSaveTimer >= (m_nAutosave*60))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
m_nSaveTimer = 0;
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_strTempFile.IsEmpty())
|
|
|
|
{
|
|
|
|
char tmpFile[_MAX_PATH], out[_MAX_PATH];
|
|
|
|
GetTempPath (_MAX_PATH, out);
|
|
|
|
GetTempFileName (out, "~LC", 0, tmpFile);
|
|
|
|
DeleteFile (tmpFile);
|
|
|
|
if (char *ptr = strchr(tmpFile, '.')) *ptr = 0;
|
|
|
|
strcat (tmpFile, ".lcd");
|
|
|
|
m_strTempFile = tmpFile;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CFile file (m_strTempFile, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
|
|
|
|
m_bUndo = TRUE;
|
|
|
|
file.SeekToBegin();
|
|
|
|
CArchive ar(&file, CArchive::store);
|
|
|
|
Serialize(ar);
|
|
|
|
ar.Close();
|
|
|
|
m_bUndo = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
unsigned char Project::GetLastStep()
|
|
|
|
{
|
|
|
|
unsigned char last = 1;
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
last = lcMax(last, mPieces[PieceIdx]->GetStepShow());
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return last;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::FindPiece(bool FindFirst, bool SearchForward)
|
|
|
|
{
|
|
|
|
if (mPieces.IsEmpty())
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int StartIdx = mPieces.GetSize() - 1;
|
|
|
|
if (!FindFirst)
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused() && Piece->IsVisible(m_nCurStep))
|
|
|
|
{
|
|
|
|
StartIdx = PieceIdx;
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int CurrentIdx = StartIdx;
|
|
|
|
Object* Focus = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (SearchForward)
|
|
|
|
CurrentIdx++;
|
|
|
|
else
|
|
|
|
CurrentIdx--;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (CurrentIdx < 0)
|
|
|
|
CurrentIdx = mPieces.GetSize() - 1;
|
|
|
|
else if (CurrentIdx >= mPieces.GetSize())
|
|
|
|
CurrentIdx = 0;
|
2014-02-16 08:23:55 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (CurrentIdx == StartIdx)
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Current = mPieces[CurrentIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Current->IsVisible(m_nCurStep))
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((!mSearchOptions.MatchInfo || Current->mPieceInfo == mSearchOptions.Info) &&
|
|
|
|
(!mSearchOptions.MatchColor || Current->mColorIndex == mSearchOptions.ColorIndex) &&
|
|
|
|
(!mSearchOptions.MatchName || strcasestr(Current->GetName(), mSearchOptions.Name)))
|
|
|
|
{
|
|
|
|
Focus = Current;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ClearSelectionAndSetFocus(Focus, LC_PIECE_SECTION_POSITION);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ZoomExtents(int FirstView, int LastView)
|
|
|
|
{
|
|
|
|
if (mPieces.IsEmpty())
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Center((bs[0] + bs[3]) / 2, (bs[1] + bs[4]) / 2, (bs[2] + bs[5]) / 2);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Points[8] =
|
|
|
|
{
|
|
|
|
lcVector3(bs[0], bs[1], bs[5]),
|
|
|
|
lcVector3(bs[3], bs[1], bs[5]),
|
|
|
|
lcVector3(bs[0], bs[1], bs[2]),
|
|
|
|
lcVector3(bs[3], bs[4], bs[5]),
|
|
|
|
lcVector3(bs[3], bs[4], bs[2]),
|
|
|
|
lcVector3(bs[0], bs[4], bs[2]),
|
|
|
|
lcVector3(bs[0], bs[4], bs[5]),
|
|
|
|
lcVector3(bs[3], bs[1], bs[2])
|
|
|
|
};
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int vp = FirstView; vp < LastView; vp++)
|
|
|
|
{
|
|
|
|
View* view = Views[vp];
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-21 00:15:42 +02:00
|
|
|
view->mCamera->ZoomExtents(view, Center, Points, 8, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::GetPiecesUsed(lcArray<lcPiecesUsedEntry>& PiecesUsed) const
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->mPieceInfo->m_strDescription[0] == '~')
|
|
|
|
continue;
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int UsedIdx;
|
2012-08-09 00:11:23 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (UsedIdx = 0; UsedIdx < PiecesUsed.GetSize(); UsedIdx++)
|
|
|
|
{
|
|
|
|
if (PiecesUsed[UsedIdx].Info != Piece->mPieceInfo || PiecesUsed[UsedIdx].ColorIndex != Piece->mColorIndex)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
PiecesUsed[UsedIdx].Count++;
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (UsedIdx == PiecesUsed.GetSize())
|
|
|
|
{
|
|
|
|
lcPiecesUsedEntry& Entry = PiecesUsed.Add();
|
|
|
|
|
|
|
|
Entry.Info = Piece->mPieceInfo;
|
|
|
|
Entry.ColorIndex = Piece->mColorIndex;
|
|
|
|
Entry.Count = 1;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a series of pictures
|
|
|
|
void Project::CreateImages(Image* images, int width, int height, unsigned short from, unsigned short to, bool hilite)
|
|
|
|
{
|
|
|
|
if (!GL_BeginRenderToTexture(width, height))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Error creating images.", LC_MB_ICONERROR | LC_MB_OK);
|
|
|
|
return;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
unsigned short oldtime;
|
|
|
|
unsigned char* buf = (unsigned char*)malloc (width*height*3);
|
|
|
|
oldtime = m_nCurStep;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
View view(this);
|
|
|
|
view.SetCamera(gMainWindow->GetActiveView()->mCamera, false);
|
|
|
|
view.mWidth = width;
|
|
|
|
view.mHeight = height;
|
|
|
|
view.SetContext(gMainWindow->mPreviewWidget->mContext);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!hilite)
|
|
|
|
SelectAndFocusNone(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RenderInitialize();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int i = from; i <= to; i++)
|
|
|
|
{
|
|
|
|
m_nCurStep = i;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (hilite)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
Piece->SetSelected(Piece->GetStepShow() == i);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CalculateStep();
|
|
|
|
Render(&view, true);
|
|
|
|
images[i-from].FromOpenGL(width, height);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (hilite)
|
|
|
|
SelectAndFocusNone(false);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
m_nCurStep = (unsigned char)oldtime;
|
|
|
|
CalculateStep();
|
|
|
|
free (buf);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GL_EndRenderToTexture();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::CreateHTMLPieceList(FILE* f, int nStep, bool bImages, const char* ext)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
int* ColorsUsed = new int[gColorList.GetSize()];
|
|
|
|
memset(ColorsUsed, 0, sizeof(ColorsUsed[0]) * gColorList.GetSize());
|
|
|
|
int* PiecesUsed = new int[gColorList.GetSize()];
|
|
|
|
int NumColors = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((Piece->GetStepShow() == nStep) || (nStep == 0))
|
|
|
|
ColorsUsed[Piece->mColorIndex]++;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("<br><table border=1><tr><td><center>Piece</center></td>\n",f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
|
|
|
|
{
|
|
|
|
if (ColorsUsed[ColorIdx])
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
ColorsUsed[ColorIdx] = NumColors;
|
|
|
|
NumColors++;
|
|
|
|
fprintf(f, "<td><center>%s</center></td>\n", gColorList[ColorIdx].Name);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
|
|
|
NumColors++;
|
|
|
|
fputs("</tr>\n",f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
PieceInfo* pInfo;
|
|
|
|
for (int j = 0; j < lcGetPiecesLibrary()->mPieces.GetSize(); j++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Add = false;
|
|
|
|
memset(PiecesUsed, 0, sizeof(PiecesUsed[0]) * gColorList.GetSize());
|
|
|
|
pInfo = lcGetPiecesLibrary()->mPieces[j];
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((Piece->mPieceInfo == pInfo) && ((Piece->GetStepShow() == nStep) || (nStep == 0)))
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
PiecesUsed[Piece->mColorIndex]++;
|
|
|
|
Add = true;
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Add)
|
|
|
|
{
|
|
|
|
if (bImages)
|
|
|
|
fprintf(f, "<tr><td><IMG SRC=\"%s%s\" ALT=\"%s\"></td>\n", pInfo->m_strName, ext, pInfo->m_strDescription);
|
|
|
|
else
|
|
|
|
fprintf(f, "<tr><td>%s</td>\n", pInfo->m_strDescription);
|
|
|
|
|
|
|
|
int curcol = 1;
|
|
|
|
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (PiecesUsed[ColorIdx])
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
while (curcol != ColorsUsed[ColorIdx] + 1)
|
|
|
|
{
|
|
|
|
fputs("<td><center>-</center></td>\n", f);
|
|
|
|
curcol++;
|
|
|
|
}
|
2013-08-31 23:58:47 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fprintf(f, "<td><center>%d</center></td>\n", PiecesUsed[ColorIdx]);
|
|
|
|
curcol++;
|
|
|
|
}
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
while (curcol != NumColors)
|
2013-08-31 23:58:47 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("<td><center>-</center></td>\n", f);
|
|
|
|
curcol++;
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</tr>\n", f);
|
2013-08-31 23:58:47 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</table>\n<br>", f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
delete[] PiecesUsed;
|
|
|
|
delete[] ColorsUsed;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::Export3DStudio()
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mPieces.IsEmpty())
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Nothing to export.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
|
|
|
return;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char FileName[LC_MAXPATH];
|
|
|
|
memset(FileName, 0, sizeof(FileName));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_3DSTUDIO, FileName))
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcDiskFile File;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!File.Open(FileName, "wb"))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long M3DStart = File.GetPosition();
|
|
|
|
File.WriteU16(0x4D4D); // CHK_M3DMAGIC
|
|
|
|
File.WriteU32(0);
|
2012-08-22 03:13:32 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0002); // CHK_M3D_VERSION
|
|
|
|
File.WriteU32(10);
|
|
|
|
File.WriteU32(3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long MDataStart = File.GetPosition();
|
|
|
|
File.WriteU16(0x3D3D); // CHK_MDATA
|
|
|
|
File.WriteU32(0);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x3D3E); // CHK_MESH_VERSION
|
|
|
|
File.WriteU32(10);
|
|
|
|
File.WriteU32(3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const int MaterialNameLength = 11;
|
|
|
|
char MaterialName[32];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcColor* Color = &gColorList[ColorIdx];
|
2014-04-09 00:34:50 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(MaterialName, "Material%03d", ColorIdx);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long MaterialStart = File.GetPosition();
|
|
|
|
File.WriteU16(0xAFFF); // CHK_MAT_ENTRY
|
|
|
|
File.WriteU32(0);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA000); // CHK_MAT_NAME
|
|
|
|
File.WriteU32(6 + MaterialNameLength + 1);
|
|
|
|
File.WriteBuffer(MaterialName, MaterialNameLength + 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA010); // CHK_MAT_AMBIENT
|
|
|
|
File.WriteU32(24);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0011); // CHK_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * Color->Value[0] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[1] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[2] + 0.5));
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0012); // CHK_LIN_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * Color->Value[0] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[1] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[2] + 0.5));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA020); // CHK_MAT_AMBIENT
|
|
|
|
File.WriteU32(24);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0011); // CHK_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * Color->Value[0] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[1] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[2] + 0.5));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0012); // CHK_LIN_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * Color->Value[0] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[1] + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * Color->Value[2] + 0.5));
|
2012-08-22 03:13:32 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA030); // CHK_MAT_SPECULAR
|
|
|
|
File.WriteU32(24);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0011); // CHK_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
2014-04-09 00:34:50 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0012); // CHK_LIN_COLOR_24
|
|
|
|
File.WriteU32(9);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
|
|
|
File.WriteU8(floor(255.0 * 0.9f + 0.5));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA040); // CHK_MAT_SHININESS
|
|
|
|
File.WriteU32(14);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * 0.25 + 0.5));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA041); // CHK_MAT_SHIN2PCT
|
|
|
|
File.WriteU32(14);
|
2013-08-17 00:39:47 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * 0.05 + 0.5));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA050); // CHK_MAT_TRANSPARENCY
|
|
|
|
File.WriteU32(14);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * (1.0f - Color->Value[3]) + 0.5));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA052); // CHK_MAT_XPFALL
|
|
|
|
File.WriteU32(14);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * 0.0 + 0.5));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA053); // CHK_MAT_REFBLUR
|
|
|
|
File.WriteU32(14);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * 0.2 + 0.5));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA100); // CHK_MAT_SHADING
|
|
|
|
File.WriteU32(8);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16(3);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA084); // CHK_MAT_SELF_ILPCT
|
|
|
|
File.WriteU32(14);
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0030); // CHK_INT_PERCENTAGE
|
|
|
|
File.WriteU32(8);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16((lcuint8)floor(100.0 * 0.0 + 0.5));
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA081); // CHK_MAT_TWO_SIDE
|
|
|
|
File.WriteU32(6);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xA087); // CHK_MAT_WIRE_SIZE
|
|
|
|
File.WriteU32(10);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(1.0f);
|
|
|
|
|
|
|
|
long MaterialEnd = File.GetPosition();
|
|
|
|
File.Seek(MaterialStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(MaterialEnd - MaterialStart);
|
|
|
|
File.Seek(MaterialEnd, SEEK_SET);
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0100); // CHK_MASTER_SCALE
|
|
|
|
File.WriteU32(10);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(1.0f);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1400); // CHK_LO_SHADOW_BIAS
|
|
|
|
File.WriteU32(10);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(1.0f);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1420); // CHK_SHADOW_MAP_SIZE
|
|
|
|
File.WriteU32(8);
|
2012-12-13 01:20:40 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16(512);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1450); // CHK_SHADOW_FILTER
|
|
|
|
File.WriteU32(10);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(3.0f);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1460); // CHK_RAY_BIAS
|
|
|
|
File.WriteU32(10);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(1.0f);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1500); // CHK_O_CONSTS
|
|
|
|
File.WriteU32(18);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(0.0f);
|
2013-01-24 00:56:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2100); // CHK_AMBIENT_LIGHT
|
|
|
|
File.WriteU32(42);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mAmbientColor, 3);
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0013); // CHK_LIN_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mAmbientColor, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1200); // CHK_SOLID_BGND
|
|
|
|
File.WriteU32(42);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundSolidColor, 3);
|
2012-02-05 03:50:57 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0013); // CHK_LIN_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundSolidColor, 3);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1100); // CHK_BIT_MAP
|
|
|
|
File.WriteU32(6 + 1 + strlen(mProperties.mBackgroundImage.Buffer()));
|
|
|
|
File.WriteBuffer(mProperties.mBackgroundImage.Buffer(), strlen(mProperties.mBackgroundImage.Buffer()) + 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1300); // CHK_V_GRADIENT
|
|
|
|
File.WriteU32(118);
|
2012-04-21 01:27:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(1.0f);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2012-04-21 01:27:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundGradientColor1, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0013); // CHK_LIN_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundGradientColor1, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats((mProperties.mBackgroundGradientColor1 + mProperties.mBackgroundGradientColor2) / 2.0f, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0013); // CHK_LIN_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats((mProperties.mBackgroundGradientColor1 + mProperties.mBackgroundGradientColor2) / 2.0f, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundGradientColor2, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0013); // CHK_LIN_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2012-04-21 01:27:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mBackgroundGradientColor2, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mProperties.mBackgroundType == LC_BACKGROUND_GRADIENT)
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1301); // LIB3DS_USE_V_GRADIENT
|
|
|
|
File.WriteU32(6);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else if (mProperties.mBackgroundType == LC_BACKGROUND_IMAGE)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x1101); // LIB3DS_USE_BIT_MAP
|
|
|
|
File.WriteU32(6);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
File.WriteU16(0x1201); // LIB3DS_USE_SOLID_BGND
|
|
|
|
File.WriteU32(6);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2200); // CHK_FOG
|
|
|
|
File.WriteU32(46);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(1000.0f);
|
|
|
|
File.WriteFloat(100.0f);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mFogColor, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2210); // CHK_FOG_BGND
|
|
|
|
File.WriteU32(6);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2302); // CHK_LAYER_FOG
|
|
|
|
File.WriteU32(40);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(100.0f);
|
|
|
|
File.WriteFloat(50.0f);
|
|
|
|
File.WriteU32(0x00100000);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x0010); // CHK_COLOR_F
|
|
|
|
File.WriteU32(18);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloats(mProperties.mFogColor, 3);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2300); // CHK_DISTANCE_CUE
|
|
|
|
File.WriteU32(28);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(0.0f);
|
|
|
|
File.WriteFloat(1000.0f);
|
|
|
|
File.WriteFloat(100.0f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x2310); // CHK_DICHK_DCUE_BGNDSTANCE_CUE
|
|
|
|
File.WriteU32(6);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int NumPieces = 0;
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* piece = mPieces[PieceIdx];
|
|
|
|
PieceInfo* Info = piece->mPieceInfo;
|
|
|
|
lcMesh* Mesh = Info->mMesh;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Mesh->mIndexType == GL_UNSIGNED_INT)
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long NamedObjectStart = File.GetPosition();
|
|
|
|
File.WriteU16(0x4000); // CHK_NAMED_OBJECT
|
|
|
|
File.WriteU32(0);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char Name[32];
|
|
|
|
sprintf(Name, "Piece%.3d", NumPieces);
|
|
|
|
NumPieces++;
|
|
|
|
File.WriteBuffer(Name, strlen(Name) + 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long TriObjectStart = File.GetPosition();
|
|
|
|
File.WriteU16(0x4100); // CHK_N_TRI_OBJECT
|
|
|
|
File.WriteU32(0);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x4110); // CHK_POINT_ARRAY
|
|
|
|
File.WriteU32(8 + 12 * Mesh->mNumVertices);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(Mesh->mNumVertices);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float* Verts = (float*)Mesh->mVertexBuffer.mData;
|
|
|
|
const lcMatrix44& ModelWorld = piece->mModelWorld;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int VertexIdx = 0; VertexIdx < Mesh->mNumVertices; VertexIdx++)
|
|
|
|
{
|
|
|
|
lcVector3 Pos(Verts[VertexIdx * 3], Verts[VertexIdx * 3 + 1], Verts[VertexIdx * 3 + 2]);
|
|
|
|
Pos = lcMul31(Pos, ModelWorld);
|
|
|
|
File.WriteFloat(Pos[0]);
|
|
|
|
File.WriteFloat(Pos[1]);
|
|
|
|
File.WriteFloat(Pos[2]);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x4160); // CHK_MESH_MATRIX
|
|
|
|
File.WriteU32(54);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMatrix44 Matrix = lcMatrix44Identity();
|
|
|
|
File.WriteFloats(Matrix[0], 3);
|
|
|
|
File.WriteFloats(Matrix[1], 3);
|
|
|
|
File.WriteFloats(Matrix[2], 3);
|
|
|
|
File.WriteFloats(Matrix[3], 3);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x4165); // CHK_MESH_COLOR
|
|
|
|
File.WriteU32(7);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU8(0);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long FaceArrayStart = File.GetPosition();
|
|
|
|
File.WriteU16(0x4120); // CHK_FACE_ARRAY
|
|
|
|
File.WriteU32(0);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int NumTriangles = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
|
|
|
|
{
|
|
|
|
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Section->PrimitiveType != GL_TRIANGLES)
|
|
|
|
continue;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
NumTriangles += Section->NumIndices / 3;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(NumTriangles);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
|
|
|
|
{
|
|
|
|
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Section->PrimitiveType != GL_TRIANGLES)
|
|
|
|
continue;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcuint16* Indices = (lcuint16*)Mesh->mIndexBuffer.mData + Section->IndexOffset / sizeof(lcuint16);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3)
|
|
|
|
{
|
|
|
|
File.WriteU16(Indices[IndexIdx + 0]);
|
|
|
|
File.WriteU16(Indices[IndexIdx + 1]);
|
|
|
|
File.WriteU16(Indices[IndexIdx + 2]);
|
|
|
|
File.WriteU16(7);
|
|
|
|
}
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
NumTriangles = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
|
|
|
|
{
|
|
|
|
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Section->PrimitiveType != GL_TRIANGLES)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int MaterialIndex = Section->ColorIndex == gDefaultColor ? piece->mColorIndex : Section->ColorIndex;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0x4130); // CHK_MSH_MAT_GROUP
|
|
|
|
File.WriteU32(6 + MaterialNameLength + 1 + 2 + 2 * Section->NumIndices / 3);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(MaterialName, "Material%03d", MaterialIndex);
|
|
|
|
File.WriteBuffer(MaterialName, MaterialNameLength + 1);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(Section->NumIndices / 3);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int IndexIdx = 0; IndexIdx < Section->NumIndices; IndexIdx += 3)
|
|
|
|
File.WriteU16(NumTriangles++);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long FaceArrayEnd = File.GetPosition();
|
|
|
|
File.Seek(FaceArrayStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(FaceArrayEnd - FaceArrayStart);
|
|
|
|
File.Seek(FaceArrayEnd, SEEK_SET);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long TriObjectEnd = File.GetPosition();
|
|
|
|
File.Seek(TriObjectStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(TriObjectEnd - TriObjectStart);
|
|
|
|
File.Seek(TriObjectEnd, SEEK_SET);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long NamedObjectEnd = File.GetPosition();
|
|
|
|
File.Seek(NamedObjectStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(NamedObjectEnd - NamedObjectStart);
|
|
|
|
File.Seek(NamedObjectEnd, SEEK_SET);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long MDataEnd = File.GetPosition();
|
|
|
|
File.Seek(MDataStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(MDataEnd - MDataStart);
|
|
|
|
File.Seek(MDataEnd, SEEK_SET);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long KFDataStart = File.GetPosition();
|
|
|
|
File.WriteU16(0xB000); // CHK_KFDATA
|
|
|
|
File.WriteU32(0);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteU16(0xB00A); // LIB3DS_KFHDR
|
|
|
|
File.WriteU32(6 + 2 + 1 + 4);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
File.WriteS16(5);
|
|
|
|
File.WriteU8(0);
|
|
|
|
File.WriteS32(100);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long KFDataEnd = File.GetPosition();
|
|
|
|
File.Seek(KFDataStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(KFDataEnd - KFDataStart);
|
|
|
|
File.Seek(KFDataEnd, SEEK_SET);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
long M3DEnd = File.GetPosition();
|
|
|
|
File.Seek(M3DStart + 2, SEEK_SET);
|
|
|
|
File.WriteU32(M3DEnd - M3DStart);
|
|
|
|
File.Seek(M3DEnd, SEEK_SET);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ExportPOVRay(lcFile& POVFile)
|
|
|
|
{
|
|
|
|
char Line[1024];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
|
|
|
char* PieceTable = new char[Library->mPieces.GetSize() * LC_PIECE_NAME_LEN];
|
|
|
|
int* PieceFlags = new int[Library->mPieces.GetSize()];
|
|
|
|
int NumColors = gColorList.GetSize();
|
|
|
|
char* ColorTable = new char[NumColors * LC_MAX_COLOR_NAME];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
memset(PieceTable, 0, Library->mPieces.GetSize() * LC_PIECE_NAME_LEN);
|
|
|
|
memset(PieceFlags, 0, Library->mPieces.GetSize() * sizeof(int));
|
|
|
|
memset(ColorTable, 0, NumColors * LC_MAX_COLOR_NAME);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
LGEO_PIECE_LGEO = 0x01,
|
|
|
|
LGEO_PIECE_AR = 0x02,
|
|
|
|
LGEO_PIECE_SLOPE = 0x04
|
|
|
|
};
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
LGEO_COLOR_SOLID = 0x01,
|
|
|
|
LGEO_COLOR_TRANSPARENT = 0x02,
|
|
|
|
LGEO_COLOR_CHROME = 0x04,
|
|
|
|
LGEO_COLOR_PEARL = 0x08,
|
|
|
|
LGEO_COLOR_METALLIC = 0x10,
|
|
|
|
LGEO_COLOR_RUBBER = 0x20,
|
|
|
|
LGEO_COLOR_GLITTER = 0x40
|
|
|
|
};
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char LGEOPath[LC_MAXPATH];
|
|
|
|
strcpy(LGEOPath, lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH));
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Parse LGEO tables.
|
|
|
|
if (LGEOPath[0])
|
|
|
|
{
|
|
|
|
lcDiskFile TableFile, ColorFile;
|
|
|
|
char Filename[LC_MAXPATH];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int Length = strlen(LGEOPath);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((LGEOPath[Length - 1] != '\\') && (LGEOPath[Length - 1] != '/'))
|
|
|
|
strcat(LGEOPath, "/");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(Filename, LGEOPath);
|
|
|
|
strcat(Filename, "lg_elements.lst");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!TableFile.Open(Filename, "rt"))
|
|
|
|
{
|
|
|
|
delete[] PieceTable;
|
|
|
|
delete[] PieceFlags;
|
|
|
|
gMainWindow->DoMessageBox("Could not find LGEO files.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
return;
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
while (TableFile.ReadLine(Line, sizeof(Line)))
|
|
|
|
{
|
|
|
|
char Src[1024], Dst[1024], Flags[1024];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (*Line == ';')
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (sscanf(Line,"%s%s%s", Src, Dst, Flags) != 3)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strupr(Src);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
PieceInfo* Info = Library->FindPiece(Src, false);
|
|
|
|
if (!Info)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int Index = Library->mPieces.FindIndex(Info);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (strchr(Flags, 'L'))
|
|
|
|
{
|
|
|
|
PieceFlags[Index] |= LGEO_PIECE_LGEO;
|
|
|
|
sprintf(PieceTable + Index * LC_PIECE_NAME_LEN, "lg_%s", Dst);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (strchr(Flags, 'A'))
|
|
|
|
{
|
|
|
|
PieceFlags[Index] |= LGEO_PIECE_AR;
|
|
|
|
sprintf(PieceTable + Index * LC_PIECE_NAME_LEN, "ar_%s", Dst);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (strchr(Flags, 'S'))
|
|
|
|
PieceFlags[Index] |= LGEO_PIECE_SLOPE;
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(Filename, LGEOPath);
|
|
|
|
strcat(Filename, "lg_colors.lst");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!ColorFile.Open(Filename, "rt"))
|
|
|
|
{
|
|
|
|
delete[] PieceTable;
|
|
|
|
delete[] PieceFlags;
|
|
|
|
gMainWindow->DoMessageBox("Could not find LGEO files.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
return;
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
while (ColorFile.ReadLine(Line, sizeof(Line)))
|
|
|
|
{
|
|
|
|
char Name[1024], Flags[1024];
|
|
|
|
int Code;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (*Line == ';')
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (sscanf(Line,"%d%s%s", &Code, Name, Flags) != 3)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int Color = lcGetColorIndex(Code);
|
|
|
|
if (Color >= NumColors)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(&ColorTable[Color * LC_MAX_COLOR_NAME], Name);
|
|
|
|
}
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Add includes.
|
|
|
|
if (LGEOPath[0])
|
|
|
|
{
|
|
|
|
POVFile.WriteLine("#include \"lg_defs.inc\"\n#include \"lg_color.inc\"\n\n");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* piece = mPieces[PieceIdx];
|
|
|
|
PieceInfo* Info = piece->mPieceInfo;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CheckIdx = 0; CheckIdx < mPieces.GetSize(); CheckIdx++)
|
|
|
|
{
|
|
|
|
if (mPieces[CheckIdx]->mPieceInfo != Info)
|
|
|
|
continue;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (CheckIdx != PieceIdx)
|
|
|
|
break;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int Index = Library->mPieces.FindIndex(Info);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (PieceTable[Index * LC_PIECE_NAME_LEN])
|
|
|
|
{
|
|
|
|
sprintf(Line, "#include \"%s.inc\"\n", PieceTable + Index * LC_PIECE_NAME_LEN);
|
|
|
|
POVFile.WriteLine(Line);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
POVFile.WriteLine("\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
POVFile.WriteLine("#include \"colors.inc\"\n\n");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Add color definitions.
|
|
|
|
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
|
|
|
|
{
|
|
|
|
lcColor* Color = &gColorList[ColorIdx];
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (lcIsColorTranslucent(ColorIdx))
|
|
|
|
{
|
|
|
|
sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> filter 0.9 } finish { ambient 0.3 diffuse 0.2 reflection 0.25 phong 0.3 phong_size 60 } }\n",
|
|
|
|
Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> } finish { ambient 0.1 phong 0.2 phong_size 20 } }\n",
|
|
|
|
Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
POVFile.WriteLine(Line);
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!ColorTable[ColorIdx * LC_MAX_COLOR_NAME])
|
|
|
|
sprintf(&ColorTable[ColorIdx * LC_MAX_COLOR_NAME], "lc_%s", Color->SafeName);
|
|
|
|
}
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
POVFile.WriteLine("\n");
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Add pieces not included in LGEO.
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
PieceInfo* Info = Piece->mPieceInfo;
|
|
|
|
int Index = Library->mPieces.FindIndex(Info);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (PieceTable[Index * LC_PIECE_NAME_LEN])
|
2013-08-09 06:57:18 +02:00
|
|
|
continue;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char Name[LC_PIECE_NAME_LEN];
|
|
|
|
char* Ptr;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(Name, Info->m_strName);
|
|
|
|
while ((Ptr = strchr(Name, '-')))
|
|
|
|
*Ptr = '_';
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(PieceTable + Index * LC_PIECE_NAME_LEN, "lc_%s", Name);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Info->mMesh->ExportPOVRay(POVFile, Name, ColorTable);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
POVFile.WriteLine("}\n\n");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, "#declare lc_%s_clear = lc_%s\n\n", Name, Name);
|
|
|
|
POVFile.WriteLine(Line);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcCamera* Camera = gMainWindow->GetActiveView()->mCamera;
|
|
|
|
const lcVector3& Position = Camera->mPosition;
|
|
|
|
const lcVector3& Target = Camera->mTargetPosition;
|
|
|
|
const lcVector3& Up = Camera->mUpVector;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, "camera {\n sky<%1g,%1g,%1g>\n location <%1g, %1g, %1g>\n look_at <%1g, %1g, %1g>\n angle %.0f\n}\n\n",
|
|
|
|
Up[0], Up[1], Up[2], Position[1], Position[0], Position[2], Target[1], Target[0], Target[2], Camera->m_fovy);
|
|
|
|
POVFile.WriteLine(Line);
|
|
|
|
sprintf(Line, "background { color rgb <%1g, %1g, %1g> }\n\nlight_source { <0, 0, 20> White shadowless }\n\n",
|
|
|
|
mProperties.mBackgroundSolidColor[0], mProperties.mBackgroundSolidColor[1], mProperties.mBackgroundSolidColor[2]);
|
|
|
|
POVFile.WriteLine(Line);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
int Index = Library->mPieces.FindIndex(Piece->mPieceInfo);
|
|
|
|
int Color;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Color = Piece->mColorIndex;
|
|
|
|
const char* Suffix = lcIsColorTranslucent(Color) ? "_clear" : "";
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const float* f = Piece->mModelWorld;
|
2013-08-29 08:51:36 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (PieceFlags[Index] & LGEO_PIECE_SLOPE)
|
|
|
|
{
|
|
|
|
sprintf(Line, "merge {\n object {\n %s%s\n texture { %s }\n }\n"
|
|
|
|
" object {\n %s_slope\n texture { %s normal { bumps 0.3 scale 0.02 } }\n }\n"
|
|
|
|
" matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
|
|
|
PieceTable + Index * LC_PIECE_NAME_LEN, Suffix, &ColorTable[Color * LC_MAX_COLOR_NAME], PieceTable + Index * LC_PIECE_NAME_LEN, &ColorTable[Color * LC_MAX_COLOR_NAME],
|
|
|
|
-f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13], f[12], f[14]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sprintf(Line, "object {\n %s%s\n texture { %s }\n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
|
|
|
PieceTable + Index * LC_PIECE_NAME_LEN, Suffix, &ColorTable[Color * LC_MAX_COLOR_NAME], -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13], f[12], f[14]);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
POVFile.WriteLine(Line);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
delete[] PieceTable;
|
|
|
|
delete[] PieceFlags;
|
|
|
|
setlocale(LC_NUMERIC, OldLocale);
|
|
|
|
POVFile.Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::HandleCommand(LC_COMMANDS id)
|
|
|
|
{
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case LC_FILE_NEW:
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!SaveModified())
|
|
|
|
return; // leave the original one
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
OnNewDocument();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_OPEN:
|
|
|
|
{
|
|
|
|
char FileName[LC_MAXPATH];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_strPathName[0])
|
|
|
|
strcpy(FileName, m_strPathName);
|
|
|
|
else
|
|
|
|
strcpy(FileName, lcGetProfileString(LC_PROFILE_PROJECTS_PATH));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (gMainWindow->DoDialog(LC_DIALOG_OPEN_PROJECT, FileName))
|
|
|
|
OpenProject(FileName);
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_MERGE:
|
|
|
|
{
|
|
|
|
char FileName[LC_MAXPATH];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_strPathName[0])
|
|
|
|
strcpy(FileName, m_strPathName);
|
|
|
|
else
|
|
|
|
strcpy(FileName, lcGetProfileString(LC_PROFILE_PROJECTS_PATH));
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (gMainWindow->DoDialog(LC_DIALOG_MERGE_PROJECT, FileName))
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcDiskFile file;
|
|
|
|
if (file.Open(FileName, "rb"))
|
|
|
|
{
|
|
|
|
if (file.GetLength() != 0)
|
|
|
|
{
|
|
|
|
FileLoad(&file, false, true);
|
|
|
|
CheckPoint("Merging");
|
|
|
|
}
|
|
|
|
file.Close();
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_SAVE:
|
|
|
|
{
|
|
|
|
DoSave(m_strPathName);
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_SAVEAS:
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
DoSave(NULL);
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_SAVE_IMAGE:
|
|
|
|
{
|
|
|
|
lcImageDialogOptions Options;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int ImageOptions = lcGetProfileInt(LC_PROFILE_IMAGE_OPTIONS);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Options.Format = (LC_IMAGE_FORMAT)(ImageOptions & ~(LC_IMAGE_MASK));
|
|
|
|
Options.Transparent = (ImageOptions & LC_IMAGE_TRANSPARENT) != 0;
|
|
|
|
Options.Width = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH);
|
|
|
|
Options.Height = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_strPathName[0])
|
|
|
|
strcpy(Options.FileName, m_strPathName);
|
|
|
|
else if (m_strTitle[0])
|
|
|
|
strcpy(Options.FileName, m_strTitle);
|
|
|
|
else
|
|
|
|
strcpy(Options.FileName, "Image");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.FileName[0])
|
|
|
|
{
|
|
|
|
char* ext = strrchr(Options.FileName, '.');
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ext && (!stricmp(ext, ".lcd") || !stricmp(ext, ".dat") || !stricmp(ext, ".ldr")))
|
|
|
|
*ext = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
switch (Options.Format)
|
|
|
|
{
|
|
|
|
case LC_IMAGE_BMP: strcat(Options.FileName, ".bmp");
|
|
|
|
break;
|
|
|
|
case LC_IMAGE_JPG: strcat(Options.FileName, ".jpg");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case LC_IMAGE_PNG: strcat(Options.FileName, ".png");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Options.Start = m_nCurStep;
|
|
|
|
Options.End = m_nCurStep;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_SAVE_IMAGE, &Options))
|
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ImageOptions = Options.Format;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Transparent)
|
|
|
|
ImageOptions |= LC_IMAGE_TRANSPARENT;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcSetProfileInt(LC_PROFILE_IMAGE_OPTIONS, ImageOptions);
|
|
|
|
lcSetProfileInt(LC_PROFILE_IMAGE_WIDTH, Options.Width);
|
|
|
|
lcSetProfileInt(LC_PROFILE_IMAGE_HEIGHT, Options.Height);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Options.FileName[0])
|
|
|
|
strcpy(Options.FileName, "Image");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char* Ext = strrchr(Options.FileName, '.');
|
|
|
|
if (Ext)
|
|
|
|
{
|
|
|
|
if (!strcmp(Ext, ".jpg") || !strcmp(Ext, ".jpeg") || !strcmp(Ext, ".bmp") || !strcmp(Ext, ".png"))
|
|
|
|
*Ext = 0;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const char* ext;
|
|
|
|
switch (Options.Format)
|
|
|
|
{
|
|
|
|
case LC_IMAGE_BMP: ext = ".bmp";
|
|
|
|
break;
|
|
|
|
case LC_IMAGE_JPG: ext = ".jpg";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case LC_IMAGE_PNG: ext = ".png";
|
|
|
|
break;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Options.End = lcMin(Options.End, 255);
|
|
|
|
Options.Start = lcMax(1, Options.Start);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Start > Options.End)
|
|
|
|
{
|
|
|
|
if (Options.Start > Options.End)
|
|
|
|
{
|
|
|
|
int Temp = Options.Start;
|
|
|
|
Options.Start = Options.End;
|
|
|
|
Options.End = Temp;
|
|
|
|
}
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Image* images = new Image[Options.End - Options.Start + 1];
|
|
|
|
CreateImages(images, Options.Width, Options.Height, Options.Start, Options.End, false);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int i = 0; i <= Options.End - Options.Start; i++)
|
|
|
|
{
|
|
|
|
char filename[LC_MAXPATH];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Start != Options.End)
|
|
|
|
{
|
|
|
|
sprintf(filename, "%s%02d%s", Options.FileName, i+1, ext);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcat(Options.FileName, ext);
|
|
|
|
strcpy(filename, Options.FileName);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
images[i].FileSave(filename, Options.Format, Options.Transparent);
|
|
|
|
}
|
|
|
|
delete []images;
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_3DS:
|
|
|
|
Export3DStudio();
|
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_HTML:
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcHTMLDialogOptions Options;
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(Options.PathName, m_strPathName);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PathName[0] != 0)
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
char* Slash = strrchr(Options.PathName, '/');
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Slash == NULL)
|
|
|
|
Slash = strrchr(Options.PathName, '\\');
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Slash)
|
|
|
|
{
|
|
|
|
Slash++;
|
|
|
|
*Slash = 0;
|
|
|
|
}
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int ImageOptions = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_OPTIONS);
|
|
|
|
int HTMLOptions = lcGetProfileInt(LC_PROFILE_HTML_OPTIONS);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Options.ImageFormat = (LC_IMAGE_FORMAT)(ImageOptions & ~(LC_IMAGE_MASK));
|
|
|
|
Options.TransparentImages = (ImageOptions & LC_IMAGE_TRANSPARENT) != 0;
|
|
|
|
Options.SinglePage = (HTMLOptions & LC_HTML_SINGLEPAGE) != 0;
|
|
|
|
Options.IndexPage = (HTMLOptions & LC_HTML_INDEX) != 0;
|
|
|
|
Options.StepImagesWidth = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_WIDTH);
|
|
|
|
Options.StepImagesHeight = lcGetProfileInt(LC_PROFILE_HTML_IMAGE_HEIGHT);
|
|
|
|
Options.HighlightNewParts = (HTMLOptions & LC_HTML_HIGHLIGHT) != 0;
|
|
|
|
Options.PartsListStep = (HTMLOptions & LC_HTML_LISTSTEP) != 0;
|
|
|
|
Options.PartsListEnd = (HTMLOptions & LC_HTML_LISTEND) != 0;
|
|
|
|
Options.PartsListImages = (HTMLOptions & LC_HTML_IMAGES) != 0;
|
|
|
|
Options.PartImagesColor = lcGetColorIndex(lcGetProfileInt(LC_PROFILE_HTML_PARTS_COLOR));
|
|
|
|
Options.PartImagesWidth = lcGetProfileInt(LC_PROFILE_HTML_PARTS_WIDTH);
|
|
|
|
Options.PartImagesHeight = lcGetProfileInt(LC_PROFILE_HTML_PARTS_HEIGHT);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_HTML, &Options))
|
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
HTMLOptions = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.SinglePage)
|
|
|
|
HTMLOptions |= LC_HTML_SINGLEPAGE;
|
|
|
|
if (Options.IndexPage)
|
|
|
|
HTMLOptions |= LC_HTML_INDEX;
|
|
|
|
if (Options.HighlightNewParts)
|
|
|
|
HTMLOptions |= LC_HTML_HIGHLIGHT;
|
|
|
|
if (Options.PartsListStep)
|
|
|
|
HTMLOptions |= LC_HTML_LISTSTEP;
|
|
|
|
if (Options.PartsListEnd)
|
|
|
|
HTMLOptions |= LC_HTML_LISTEND;
|
|
|
|
if (Options.PartsListImages)
|
|
|
|
HTMLOptions |= LC_HTML_IMAGES;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ImageOptions = Options.ImageFormat;
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.TransparentImages)
|
|
|
|
ImageOptions |= LC_IMAGE_TRANSPARENT;
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_IMAGE_OPTIONS, ImageOptions);
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_OPTIONS, HTMLOptions);
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_IMAGE_WIDTH, Options.StepImagesWidth);
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_IMAGE_HEIGHT, Options.StepImagesHeight);
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_PARTS_COLOR, lcGetColorCode(Options.PartImagesColor));
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_PARTS_WIDTH, Options.PartImagesWidth);
|
|
|
|
lcSetProfileInt(LC_PROFILE_HTML_PARTS_HEIGHT, Options.PartImagesHeight);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int PathLength = strlen(Options.PathName);
|
|
|
|
if (PathLength && Options.PathName[PathLength] != '/' && Options.PathName[PathLength] != '\\')
|
|
|
|
strcat(Options.PathName, "/");
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: create directory
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: Move to its own function
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
FILE* f;
|
|
|
|
const char *ext, *htmlext;
|
|
|
|
char fn[LC_MAXPATH];
|
|
|
|
int i;
|
|
|
|
unsigned short last = GetLastStep();
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
switch (Options.ImageFormat)
|
2013-08-17 03:35:02 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_IMAGE_BMP: ext = ".bmp";
|
|
|
|
break;
|
|
|
|
case LC_IMAGE_JPG: ext = ".jpg";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case LC_IMAGE_PNG: ext = ".png";
|
|
|
|
break;
|
2013-08-17 03:35:02 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
htmlext = ".html";
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.SinglePage)
|
|
|
|
{
|
|
|
|
strcpy(fn, Options.PathName);
|
|
|
|
strcat(fn, m_strTitle);
|
|
|
|
strcat(fn, htmlext);
|
|
|
|
f = fopen (fn, "wt");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fprintf (f, "<HTML>\n<HEAD>\n<TITLE>Instructions for %s</TITLE>\n</HEAD>\n<BR>\n<CENTER>\n", m_strTitle);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (i = 1; i <= last; i++)
|
|
|
|
{
|
|
|
|
fprintf(f, "<IMG SRC=\"%s-%02d%s\" ALT=\"Step %02d\" WIDTH=%d HEIGHT=%d><BR><BR>\n",
|
|
|
|
m_strTitle, i, ext, i, Options.StepImagesWidth, Options.StepImagesHeight);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListStep)
|
|
|
|
CreateHTMLPieceList(f, i, Options.PartsListImages, ext);
|
|
|
|
}
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListEnd)
|
|
|
|
CreateHTMLPieceList(f, 0, Options.PartsListImages, ext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</CENTER>\n<BR><HR><BR><B><I>Created by <A HREF=\"http://www.leocad.org\">LeoCAD</A></B></I><BR></HTML>\n", f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Options.IndexPage)
|
|
|
|
{
|
|
|
|
strcpy(fn, Options.PathName);
|
|
|
|
strcat (fn, m_strTitle);
|
|
|
|
strcat (fn, "-index");
|
|
|
|
strcat (fn, htmlext);
|
|
|
|
f = fopen (fn, "wt");
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
|
|
|
}
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fprintf(f, "<HTML>\n<HEAD>\n<TITLE>Instructions for %s</TITLE>\n</HEAD>\n<BR>\n<CENTER>\n", m_strTitle);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (i = 1; i <= last; i++)
|
|
|
|
fprintf(f, "<A HREF=\"%s-%02d%s\">Step %d<BR>\n</A>", m_strTitle, i, htmlext, i);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListEnd)
|
|
|
|
fprintf(f, "<A HREF=\"%s-pieces%s\">Pieces Used</A><BR>\n", m_strTitle, htmlext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</CENTER>\n<BR><HR><BR><B><I>Created by <A HREF=\"http://www.leocad.org\">LeoCAD</A></B></I><BR></HTML>\n", f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Create each step
|
|
|
|
for (i = 1; i <= last; i++)
|
|
|
|
{
|
|
|
|
sprintf(fn, "%s%s-%02d%s", Options.PathName, m_strTitle, i, htmlext);
|
|
|
|
f = fopen(fn, "wt");
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
|
|
|
}
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fprintf(f, "<HTML>\n<HEAD>\n<TITLE>%s - Step %02d</TITLE>\n</HEAD>\n<BR>\n<CENTER>\n", m_strTitle, i);
|
|
|
|
fprintf(f, "<IMG SRC=\"%s-%02d%s\" ALT=\"Step %02d\" WIDTH=%d HEIGHT=%d><BR><BR>\n",
|
|
|
|
m_strTitle, i, ext, i, Options.StepImagesWidth, Options.StepImagesHeight);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListStep)
|
|
|
|
CreateHTMLPieceList(f, i, Options.PartsListImages, ext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</CENTER>\n<BR><HR><BR>", f);
|
|
|
|
if (i != 1)
|
|
|
|
fprintf(f, "<A HREF=\"%s-%02d%s\">Previous</A> ", m_strTitle, i-1, htmlext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.IndexPage)
|
|
|
|
fprintf(f, "<A HREF=\"%s-index%s\">Index</A> ", m_strTitle, htmlext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (i != last)
|
|
|
|
fprintf(f, "<A HREF=\"%s-%02d%s\">Next</A>", m_strTitle, i+1, htmlext);
|
|
|
|
else if (Options.PartsListEnd)
|
|
|
|
fprintf(f, "<A HREF=\"%s-pieces%s\">Pieces Used</A>", m_strTitle, htmlext);
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("<BR></HTML>\n",f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
2013-08-17 03:35:02 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListEnd)
|
|
|
|
{
|
|
|
|
strcpy(fn, Options.PathName);
|
|
|
|
strcat (fn, m_strTitle);
|
|
|
|
strcat (fn, "-pieces");
|
|
|
|
strcat (fn, htmlext);
|
|
|
|
f = fopen (fn, "wt");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fprintf (f, "<HTML>\n<HEAD>\n<TITLE>Pieces used by %s</TITLE>\n</HEAD>\n<BR>\n<CENTER>\n", m_strTitle);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CreateHTMLPieceList(f, 0, Options.PartsListImages, ext);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("</CENTER>\n<BR><HR><BR>", f);
|
|
|
|
fprintf(f, "<A HREF=\"%s-%02d%s\">Previous</A> ", m_strTitle, i-1, htmlext);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.IndexPage)
|
|
|
|
fprintf(f, "<A HREF=\"%s-index%s\">Index</A> ", m_strTitle, htmlext);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
fputs("<BR></HTML>\n",f);
|
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Save step pictures
|
|
|
|
Image* images = new Image[last];
|
|
|
|
CreateImages(images, Options.StepImagesWidth, Options.StepImagesHeight, 1, last, Options.HighlightNewParts);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (i = 0; i < last; i++)
|
|
|
|
{
|
|
|
|
sprintf(fn, "%s%s-%02d%s", Options.PathName, m_strTitle, i+1, ext);
|
|
|
|
images[i].FileSave(fn, Options.ImageFormat, Options.TransparentImages);
|
|
|
|
}
|
|
|
|
delete []images;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.PartsListImages)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
int cx = Options.PartImagesWidth, cy = Options.PartImagesHeight;
|
|
|
|
if (!GL_BeginRenderToTexture(cx, cy))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Error creating images.", LC_MB_ICONERROR | LC_MB_OK);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float aspect = (float)cx/(float)cy;
|
|
|
|
glViewport(0, 0, cx, cy);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
PieceInfo* pInfo;
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
bool bSkip = false;
|
|
|
|
pInfo = Piece->mPieceInfo;
|
|
|
|
|
|
|
|
for (int CheckIdx = 0; CheckIdx < PieceIdx; CheckIdx++)
|
|
|
|
{
|
|
|
|
if (mPieces[CheckIdx]->mPieceInfo == pInfo)
|
|
|
|
{
|
|
|
|
bSkip = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bSkip)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
glPolygonOffset(0.5f, 0.1f);
|
|
|
|
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
pInfo->ZoomExtents(30.0f, aspect);
|
|
|
|
pInfo->RenderPiece(Options.PartImagesColor);
|
|
|
|
glFinish();
|
|
|
|
|
|
|
|
Image image;
|
|
|
|
image.FromOpenGL (cx, cy);
|
|
|
|
|
|
|
|
sprintf(fn, "%s%s%s", Options.PathName, pInfo->m_strName, ext);
|
|
|
|
image.FileSave(fn, Options.ImageFormat, Options.TransparentImages);
|
|
|
|
}
|
|
|
|
GL_EndRenderToTexture();
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_BRICKLINK:
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mPieces.IsEmpty())
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Nothing to export.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
|
|
|
break;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char FileName[LC_MAXPATH];
|
|
|
|
memset(FileName, 0, sizeof(FileName));
|
2013-08-14 00:17:25 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_BRICKLINK, FileName))
|
|
|
|
break;
|
2013-08-14 00:17:25 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcDiskFile BrickLinkFile;
|
|
|
|
char Line[1024];
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!BrickLinkFile.Open(FileName, "wt"))
|
2012-12-13 03:51:12 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArray<lcPiecesUsedEntry> PiecesUsed;
|
|
|
|
GetPiecesUsed(PiecesUsed);
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
|
|
|
BrickLinkFile.WriteLine("<INVENTORY>\n");
|
|
|
|
|
|
|
|
for (int PieceIdx = 0; PieceIdx < PiecesUsed.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
BrickLinkFile.WriteLine(" <ITEM>\n");
|
|
|
|
BrickLinkFile.WriteLine(" <ITEMTYPE>P</ITEMTYPE>\n");
|
|
|
|
|
|
|
|
sprintf(Line, " <ITEMID>%s</ITEMID>\n", PiecesUsed[PieceIdx].Info->m_strName);
|
|
|
|
BrickLinkFile.WriteLine(Line);
|
|
|
|
|
|
|
|
int Count = PiecesUsed[PieceIdx].Count;
|
|
|
|
if (Count > 1)
|
2012-12-13 03:51:12 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, " <MINQTY>%d</MINQTY>\n", Count);
|
|
|
|
BrickLinkFile.WriteLine(Line);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Color = lcGetBrickLinkColor(PiecesUsed[PieceIdx].ColorIndex);
|
|
|
|
if (Color)
|
|
|
|
{
|
|
|
|
sprintf(Line, " <COLOR>%d</COLOR>\n", Color);
|
|
|
|
BrickLinkFile.WriteLine(Line);
|
2012-12-13 03:51:12 +01:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
BrickLinkFile.WriteLine(" </ITEM>\n");
|
2012-12-13 03:51:12 +01:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
BrickLinkFile.WriteLine("</INVENTORY>\n");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
setlocale(LC_NUMERIC, OldLocale);
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_CSV:
|
|
|
|
{
|
|
|
|
if (mPieces.IsEmpty())
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Nothing to export.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
|
|
|
break;
|
|
|
|
}
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char FileName[LC_MAXPATH];
|
|
|
|
memset(FileName, 0, sizeof(FileName));
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_CSV, FileName))
|
|
|
|
break;
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcDiskFile CSVFile;
|
|
|
|
char Line[1024];
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!CSVFile.Open(FileName, "wt"))
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK | LC_MB_ICONERROR);
|
|
|
|
break;
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArray<lcPiecesUsedEntry> PiecesUsed;
|
|
|
|
GetPiecesUsed(PiecesUsed);
|
|
|
|
|
|
|
|
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
|
|
|
CSVFile.WriteLine("Part Name,Color,Quantity,Part ID,Color Code\n");
|
|
|
|
|
|
|
|
for (int PieceIdx = 0; PieceIdx < PiecesUsed.GetSize(); PieceIdx++)
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, "\"%s\",\"%s\",%d,%s,%d\n", PiecesUsed[PieceIdx].Info->m_strDescription, gColorList[PiecesUsed[PieceIdx].ColorIndex].Name,
|
|
|
|
PiecesUsed[PieceIdx].Count, PiecesUsed[PieceIdx].Info->m_strName, gColorList[PiecesUsed[PieceIdx].ColorIndex].Code);
|
|
|
|
CSVFile.WriteLine(Line);
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
setlocale(LC_NUMERIC, OldLocale);
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_POVRAY:
|
|
|
|
{
|
|
|
|
lcPOVRayDialogOptions Options;
|
|
|
|
|
|
|
|
memset(Options.FileName, 0, sizeof(Options.FileName));
|
|
|
|
strcpy(Options.POVRayPath, lcGetProfileString(LC_PROFILE_POVRAY_PATH));
|
|
|
|
strcpy(Options.LGEOPath, lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH));
|
|
|
|
Options.Render = lcGetProfileInt(LC_PROFILE_POVRAY_RENDER);
|
|
|
|
|
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_POVRAY, &Options))
|
|
|
|
break;
|
|
|
|
|
|
|
|
lcSetProfileString(LC_PROFILE_POVRAY_PATH, Options.POVRayPath);
|
|
|
|
lcSetProfileString(LC_PROFILE_POVRAY_LGEO_PATH, Options.LGEOPath);
|
|
|
|
lcSetProfileInt(LC_PROFILE_POVRAY_RENDER, Options.Render);
|
|
|
|
|
|
|
|
lcDiskFile POVFile;
|
|
|
|
|
|
|
|
if (!POVFile.Open(Options.FileName, "wt"))
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK|LC_MB_ICONERROR);
|
|
|
|
break;
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ExportPOVRay(POVFile);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Render)
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArray<String> Arguments;
|
|
|
|
char Argument[LC_MAXPATH + 32];
|
2012-12-13 03:51:12 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Argument, "+I%s", Options.FileName);
|
|
|
|
Arguments.Add(Argument);
|
|
|
|
|
|
|
|
if (Options.LGEOPath[0])
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Argument, "+L%slg/", Options.LGEOPath);
|
|
|
|
Arguments.Add(Argument);
|
|
|
|
sprintf(Argument, "+L%sar/", Options.LGEOPath);
|
|
|
|
Arguments.Add(Argument);
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
sprintf(Argument, "+o%s", Options.FileName);
|
|
|
|
char* Slash1 = strrchr(Argument, '\\');
|
|
|
|
char* Slash2 = strrchr(Argument, '/');
|
|
|
|
if (Slash1 || Slash2)
|
2013-08-14 00:17:25 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Slash1 > Slash2)
|
|
|
|
*(Slash1 + 1) = 0;
|
|
|
|
else
|
|
|
|
*(Slash2 + 1) = 0;
|
|
|
|
|
|
|
|
Arguments.Add(Argument);
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
g_App->RunProcess(Options.POVRayPath, Arguments);
|
2013-08-14 00:17:25 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXPORT_WAVEFRONT:
|
2012-12-13 03:51:12 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
char FileName[LC_MAXPATH];
|
|
|
|
memset(FileName, 0, sizeof(FileName));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EXPORT_WAVEFRONT, FileName))
|
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcDiskFile OBJFile;
|
|
|
|
char Line[1024];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!OBJFile.Open(FileName, "wt"))
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Could not open file for writing.", LC_MB_OK|LC_MB_ICONERROR);
|
|
|
|
break;
|
2012-12-13 03:51:12 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
char buf[LC_MAXPATH], *ptr;
|
|
|
|
lcuint32 vert = 1;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const char* OldLocale = setlocale(LC_NUMERIC, "C");
|
|
|
|
strcpy(buf, m_strPathName);
|
|
|
|
ptr = strrchr(buf, '\\');
|
|
|
|
if (ptr)
|
|
|
|
ptr++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptr = strrchr(buf, '/');
|
|
|
|
if (ptr)
|
|
|
|
ptr++;
|
|
|
|
else
|
|
|
|
ptr = buf;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
OBJFile.WriteLine("# Model exported from LeoCAD\n");
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (strlen(buf) != 0)
|
|
|
|
{
|
|
|
|
sprintf(Line, "# Original name: %s\n", ptr);
|
|
|
|
OBJFile.WriteLine(Line);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!mProperties.mAuthor.IsEmpty())
|
|
|
|
{
|
|
|
|
sprintf(Line, "# Author: %s\n", mProperties.mAuthor.Buffer());
|
|
|
|
OBJFile.WriteLine(Line);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(buf, FileName);
|
|
|
|
ptr = strrchr(buf, '.');
|
|
|
|
if (ptr)
|
|
|
|
*ptr = 0;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcat(buf, ".mtl");
|
|
|
|
ptr = strrchr(buf, '\\');
|
|
|
|
if (ptr)
|
|
|
|
ptr++;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptr = strrchr(buf, '/');
|
|
|
|
if (ptr)
|
|
|
|
ptr++;
|
|
|
|
else
|
|
|
|
ptr = buf;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, "#\n\nmtllib %s\n\n", ptr);
|
|
|
|
OBJFile.WriteLine(Line);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
FILE* mat = fopen(buf, "wt");
|
|
|
|
fputs("# Colors used by LeoCAD\n# You need to add transparency values\n#\n\n", mat);
|
|
|
|
for (int ColorIdx = 0; ColorIdx < gColorList.GetSize(); ColorIdx++)
|
|
|
|
{
|
|
|
|
lcColor* Color = &gColorList[ColorIdx];
|
|
|
|
fprintf(mat, "newmtl %s\nKd %.2f %.2f %.2f\n\n", Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
|
|
|
}
|
|
|
|
fclose(mat);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
const lcMatrix44& ModelWorld = Piece->mModelWorld;
|
|
|
|
PieceInfo* pInfo = Piece->mPieceInfo;
|
|
|
|
float* Verts = (float*)pInfo->mMesh->mVertexBuffer.mData;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int i = 0; i < pInfo->mMesh->mNumVertices * 3; i += 3)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Vertex = lcMul31(lcVector3(Verts[i], Verts[i+1], Verts[i+2]), ModelWorld);
|
|
|
|
sprintf(Line, "v %.2f %.2f %.2f\n", Vertex[0], Vertex[1], Vertex[2]);
|
|
|
|
OBJFile.WriteLine(Line);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
OBJFile.WriteLine("#\n\n");
|
|
|
|
}
|
2013-01-26 02:20:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
PieceInfo* Info = Piece->mPieceInfo;
|
2013-01-26 02:20:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(buf, Piece->GetName());
|
|
|
|
for (unsigned int i = 0; i < strlen(buf); i++)
|
|
|
|
if ((buf[i] == '#') || (buf[i] == ' '))
|
|
|
|
buf[i] = '_';
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
sprintf(Line, "g %s\n", buf);
|
|
|
|
OBJFile.WriteLine(Line);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Info->mMesh->ExportWavefrontIndices(OBJFile, Piece->mColorCode, vert);
|
|
|
|
vert += Info->mMesh->mNumVertices;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
setlocale(LC_NUMERIC, OldLocale);
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_PROPERTIES:
|
|
|
|
{
|
|
|
|
lcPropertiesDialogOptions Options;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Options.Properties = mProperties;
|
|
|
|
Options.Title = m_strTitle;
|
|
|
|
Options.SetDefault = false;
|
2013-01-26 02:20:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GetPiecesUsed(Options.PartsUsed);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_PROPERTIES, &Options))
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.SetDefault)
|
|
|
|
Options.Properties.SaveDefaults();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mProperties == Options.Properties)
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
mProperties = Options.Properties;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int i = 0; i < Views.GetSize (); i++)
|
|
|
|
{
|
|
|
|
Views[i]->MakeCurrent();
|
|
|
|
RenderInitialize();
|
|
|
|
}
|
2013-01-26 02:20:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Properties");
|
|
|
|
} break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_PRINT_PREVIEW:
|
|
|
|
gMainWindow->TogglePrintPreview();
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_PRINT:
|
|
|
|
gMainWindow->DoDialog(LC_DIALOG_PRINT, NULL);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: printing
|
|
|
|
case LC_FILE_PRINT_BOM:
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_TERRAIN_EDITOR:
|
|
|
|
{
|
|
|
|
// TODO: decide what to do with the terrain editor
|
|
|
|
// Terrain temp = *m_pTerrain;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// if (SystemDoDialog(LC_DLG_TERRAIN, temp))
|
|
|
|
// {
|
|
|
|
// *m_pTerrain = temp;
|
|
|
|
// m_pTerrain->LoadTexture();
|
|
|
|
// }
|
|
|
|
} break;
|
2013-01-26 02:20:34 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_RECENT1:
|
|
|
|
case LC_FILE_RECENT2:
|
|
|
|
case LC_FILE_RECENT3:
|
|
|
|
case LC_FILE_RECENT4:
|
|
|
|
{
|
|
|
|
if (!OpenProject(gMainWindow->mRecentFiles[id - LC_FILE_RECENT1]))
|
|
|
|
gMainWindow->RemoveRecentFile(id - LC_FILE_RECENT1);
|
|
|
|
} break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_FILE_EXIT:
|
|
|
|
{
|
|
|
|
gMainWindow->Close();
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_UNDO:
|
|
|
|
case LC_EDIT_REDO:
|
|
|
|
{
|
|
|
|
LC_UNDOINFO *pUndo, *pTmp;
|
|
|
|
int i;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (id == LC_EDIT_UNDO)
|
|
|
|
{
|
|
|
|
if ((m_pUndoList != NULL) && (m_pUndoList->pNext != NULL))
|
|
|
|
{
|
|
|
|
// Remove the first item from the undo list.
|
|
|
|
pUndo = m_pUndoList;
|
|
|
|
m_pUndoList = pUndo->pNext;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Check if we need to delete the last redo info.
|
|
|
|
for (pTmp = m_pRedoList, i = 0; pTmp; pTmp = pTmp->pNext, i++)
|
|
|
|
if ((i == 29) && (pTmp->pNext != NULL))
|
|
|
|
{
|
|
|
|
delete pTmp->pNext;
|
|
|
|
pTmp->pNext = NULL;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pUndo->pNext = m_pRedoList;
|
|
|
|
m_pRedoList = pUndo;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pUndo = m_pUndoList;
|
|
|
|
DeleteContents(true);
|
|
|
|
FileLoad(&pUndo->file, true, false);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_bUndoOriginal && (m_pUndoList != NULL) && (m_pUndoList->pNext == NULL))
|
|
|
|
SetModifiedFlag(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_pRedoList != NULL)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
// Remove the first element from the redo list.
|
|
|
|
pUndo = m_pRedoList;
|
|
|
|
m_pRedoList = pUndo->pNext;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Check if we can delete the last undo info.
|
|
|
|
for (pTmp = m_pUndoList, i = 0; pTmp; pTmp = pTmp->pNext, i++)
|
|
|
|
if ((i == 30) && (pTmp->pNext != NULL))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
delete pTmp->pNext;
|
|
|
|
pTmp->pNext = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Add info to the start of the undo list.
|
|
|
|
pUndo->pNext = m_pUndoList;
|
|
|
|
m_pUndoList = pUndo;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Load state.
|
|
|
|
DeleteContents(true);
|
|
|
|
FileLoad(&pUndo->file, true, false);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
gMainWindow->UpdateUndoRedo(m_pUndoList->pNext ? m_pUndoList->strText : NULL, m_pRedoList ? m_pRedoList->strText : NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_CUT:
|
|
|
|
case LC_EDIT_COPY:
|
2013-01-25 00:54:10 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMemFile* Clipboard = new lcMemFile();
|
2013-01-26 00:22:24 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int i = 0;
|
|
|
|
// Light* pLight;
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
if (mPieces[PieceIdx]->IsSelected())
|
|
|
|
i++;
|
|
|
|
Clipboard->WriteBuffer(&i, sizeof(i));
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2013-01-25 00:54:10 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
Piece->FileSave(*Clipboard);
|
|
|
|
}
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
i = mGroups.GetSize();
|
2014-05-18 01:03:05 +02:00
|
|
|
Clipboard->WriteBuffer(&i, sizeof(i));
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
mGroups[GroupIdx]->FileSave(Clipboard, mGroups);
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
i = 0;
|
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
if (mCameras[CameraIdx]->IsSelected())
|
|
|
|
i++;
|
|
|
|
Clipboard->WriteBuffer(&i, sizeof(i));
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* pCamera = mCameras[CameraIdx];
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pCamera->IsSelected())
|
|
|
|
pCamera->FileSave(*Clipboard);
|
2013-01-25 00:54:10 +01:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
/*
|
|
|
|
for (i = 0, pLight = m_pLights; pLight; pLight = pLight->m_pNext)
|
|
|
|
if (pLight->IsSelected())
|
|
|
|
i++;
|
|
|
|
Clipboard->Write(&i, sizeof(i));
|
2013-01-25 00:54:10 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (pLight = m_pLights; pLight; pLight = pLight->m_pNext)
|
|
|
|
if (pLight->IsSelected())
|
|
|
|
pLight->FileSave(Clipboard);
|
|
|
|
*/
|
|
|
|
if (id == LC_EDIT_CUT)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
RemoveSelectedObjects();
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Cutting");
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
g_App->ExportClipboard(Clipboard);
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_PASTE:
|
|
|
|
{
|
|
|
|
lcFile* file = g_App->mClipboard;
|
|
|
|
if (file == NULL)
|
2013-08-09 06:57:18 +02:00
|
|
|
break;
|
2014-05-18 01:03:05 +02:00
|
|
|
file->Seek(0, SEEK_SET);
|
|
|
|
SelectAndFocusNone(false);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArray<Piece*> PastedPieces;
|
2014-05-25 03:45:19 +02:00
|
|
|
int NumPieces;
|
|
|
|
file->ReadBuffer(&NumPieces, sizeof(NumPieces));
|
|
|
|
|
|
|
|
while (NumPieces--)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcPiece* Piece = new lcPiece(NULL);
|
|
|
|
Piece->FileLoad(*file);
|
|
|
|
PastedPieces.Add(Piece);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
lcArray<lcGroup*> Groups;
|
|
|
|
int NumGroups;
|
|
|
|
file->ReadBuffer(&NumGroups, sizeof(NumGroups));
|
|
|
|
|
|
|
|
while (NumGroups--)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = new lcGroup();
|
|
|
|
Group->FileLoad(file);
|
|
|
|
Groups.Add(Group);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < PastedPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcPiece* Piece = PastedPieces[PieceIdx];
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->CreateName(mPieces);
|
|
|
|
Piece->SetStepShow(m_nCurStep);
|
|
|
|
mPieces.Add(Piece);
|
|
|
|
Piece->SetSelected(true);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
int GroupIndex = LC_POINTER_TO_INT(Piece->GetGroup());
|
|
|
|
if (GroupIndex != -1)
|
|
|
|
Piece->SetGroup(Groups[GroupIndex]);
|
2014-05-18 01:03:05 +02:00
|
|
|
else
|
2014-05-25 20:23:09 +02:00
|
|
|
Piece->SetGroup(NULL);
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2012-03-07 23:59:06 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
|
2012-03-07 23:59:06 +01:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = Groups[GroupIdx];
|
|
|
|
int GroupIndex = LC_POINTER_TO_INT(Group->mGroup);
|
|
|
|
Group->mGroup = (GroupIndex != -1) ? Groups[GroupIndex] : NULL;
|
2012-03-07 23:59:06 +01:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = Groups[GroupIdx];
|
|
|
|
bool Add = false;
|
2012-03-09 23:47:05 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < PastedPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
lcPiece* Piece = PastedPieces[PieceIdx];
|
|
|
|
|
|
|
|
for (lcGroup* PieceGroup = Piece->GetGroup(); PieceGroup; PieceGroup = PieceGroup->mGroup)
|
|
|
|
{
|
|
|
|
if (PieceGroup == Group)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
Add = true;
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-25 03:45:19 +02:00
|
|
|
}
|
2012-03-09 23:47:05 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Add)
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
2012-03-09 23:47:05 +01:00
|
|
|
}
|
2013-08-17 01:17:25 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Add)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
|
|
|
int a, max = 0;
|
2012-04-14 04:20:27 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int SearchGroupIdx = 0; SearchGroupIdx < mGroups.GetSize(); SearchGroupIdx++)
|
|
|
|
{
|
|
|
|
lcGroup* SearchGroup = mGroups[SearchGroupIdx];
|
|
|
|
|
|
|
|
if (strncmp("Pasted Group #", SearchGroup ->m_strName, 14) == 0)
|
|
|
|
if (sscanf(SearchGroup ->m_strName + 14, "%d", &a) == 1)
|
2014-05-18 01:03:05 +02:00
|
|
|
if (a > max)
|
|
|
|
max = a;
|
2014-05-25 03:45:19 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
sprintf(Group->m_strName, "Pasted Group #%.2d", max+1);
|
|
|
|
mGroups.Add(Group);
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
2014-05-25 03:45:19 +02:00
|
|
|
delete Group;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2012-04-14 04:20:27 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
int NumCameras;
|
|
|
|
file->ReadBuffer(&NumCameras, sizeof(NumCameras));
|
2012-04-14 04:20:27 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
while (NumCameras--)
|
2012-04-14 04:20:27 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Camera* pCamera = new Camera(false);
|
|
|
|
pCamera->FileLoad(*file);
|
|
|
|
pCamera->CreateName(mCameras);
|
|
|
|
pCamera->SetSelected(true);
|
|
|
|
mCameras.Add(pCamera);
|
2012-04-14 04:20:27 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: lights
|
|
|
|
CalculateStep();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Pasting");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_FIND:
|
|
|
|
if (gMainWindow->DoDialog(LC_DIALOG_FIND, &mSearchOptions))
|
|
|
|
FindPiece(true, true);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_FIND_NEXT:
|
|
|
|
FindPiece(false, true);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_FIND_PREVIOUS:
|
|
|
|
FindPiece(false, false);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_SELECT_ALL:
|
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2012-04-14 04:20:27 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->SetSelected(true);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_EDIT_SELECT_NONE:
|
|
|
|
{
|
|
|
|
SelectAndFocusNone(false);
|
|
|
|
gMainWindow->UpdateFocusObject(NULL);
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_EDIT_SELECT_INVERT:
|
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->SetSelected(!Piece->IsSelected());
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_SELECT_BY_NAME:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcSelectDialogOptions Options;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
Options.Selection.Add(mPieces[PieceIdx]->IsSelected());
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
if (mCameras[CameraIdx]->IsVisible())
|
|
|
|
Options.Selection.Add(mCameras[CameraIdx]->IsSelected());
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (mLights[LightIdx]->IsVisible())
|
|
|
|
Options.Selection.Add(mLights[LightIdx]->IsSelected());
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Selection.GetSize() == 0)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Nothing to select.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
2014-02-10 01:13:41 +01:00
|
|
|
break;
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_SELECT_BY_NAME, &Options))
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SelectAndFocusNone(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int ObjectIndex = 0;
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++, ObjectIndex++)
|
|
|
|
if (Options.Selection[ObjectIndex])
|
|
|
|
mPieces[PieceIdx]->SetSelected(true);
|
|
|
|
|
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++, ObjectIndex++)
|
|
|
|
if (Options.Selection[ObjectIndex])
|
|
|
|
mCameras[CameraIdx]->SetSelected(true);
|
|
|
|
|
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (Options.Selection[ObjectIndex])
|
|
|
|
mLights[LightIdx]->SetSelected(true);
|
|
|
|
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_SPLIT_HORIZONTAL:
|
|
|
|
gMainWindow->SplitHorizontal();
|
2013-08-09 06:57:18 +02:00
|
|
|
break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_SPLIT_VERTICAL:
|
|
|
|
gMainWindow->SplitVertical();
|
2013-08-09 06:57:18 +02:00
|
|
|
break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_REMOVE_VIEW:
|
|
|
|
gMainWindow->RemoveView();
|
2013-08-09 06:57:18 +02:00
|
|
|
break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_RESET_VIEWS:
|
|
|
|
gMainWindow->ResetViews();
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_FULLSCREEN:
|
|
|
|
gMainWindow->ToggleFullScreen();
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_PROJECTION_PERSPECTIVE:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
View* ActiveView = gMainWindow->GetActiveView();
|
|
|
|
lcCamera* Camera = ActiveView->mCamera;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Camera->SetOrtho(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera->IsFocused())
|
|
|
|
gMainWindow->UpdateFocusObject(Camera);
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdatePerspective();
|
|
|
|
}
|
|
|
|
break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_PROJECTION_ORTHO:
|
|
|
|
{
|
|
|
|
View* ActiveView = gMainWindow->GetActiveView();
|
|
|
|
lcCamera* Camera = ActiveView->mCamera;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Camera->SetOrtho(true);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera->IsFocused())
|
|
|
|
gMainWindow->UpdateFocusObject(Camera);
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdatePerspective();
|
|
|
|
}
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_PROJECTION_CYCLE:
|
|
|
|
{
|
|
|
|
View* ActiveView = gMainWindow->GetActiveView();
|
|
|
|
lcCamera* Camera = ActiveView->mCamera;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Camera->SetOrtho(!Camera->IsOrtho());
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdatePerspective();
|
|
|
|
}
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_PROJECTION_FOCUS:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 FocusVector;
|
|
|
|
GetSelectionCenter(FocusVector);
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetFocalPoint(FocusVector, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_INSERT:
|
|
|
|
{
|
|
|
|
if (m_pCurPiece == NULL)
|
|
|
|
break;
|
|
|
|
Piece* Last = mPieces.IsEmpty() ? NULL : mPieces[mPieces.GetSize() - 1];
|
|
|
|
Piece* pPiece = new Piece(m_pCurPiece);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused())
|
|
|
|
{
|
|
|
|
Last = Piece;
|
|
|
|
break;
|
|
|
|
}
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Last != NULL)
|
|
|
|
{
|
|
|
|
lcVector3 Pos;
|
|
|
|
lcVector4 Rot;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GetPieceInsertPosition(Last, Pos, Rot);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pPiece->Initialize(Pos[0], Pos[1], Pos[2], m_nCurStep);
|
2012-08-22 03:13:32 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pPiece->ChangeKey(m_nCurStep, false, Rot, LC_PK_ROTATION);
|
|
|
|
pPiece->UpdatePosition(m_nCurStep);
|
2012-08-22 03:13:32 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else
|
|
|
|
pPiece->Initialize(0, 0, 0, m_nCurStep);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pPiece->SetColorIndex(gMainWindow->mColorIndex);
|
|
|
|
pPiece->CreateName(mPieces);
|
|
|
|
mPieces.Add(pPiece);
|
|
|
|
ClearSelectionAndSetFocus(pPiece, LC_PIECE_SECTION_POSITION);
|
|
|
|
SystemPieceComboAdd(m_pCurPiece->m_strDescription);
|
|
|
|
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Inserting");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_PIECE_DELETE:
|
|
|
|
{
|
|
|
|
if (RemoveSelectedObjects())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
UpdateSelection();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPoint("Deleting");
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_MOVE_PLUSX:
|
|
|
|
case LC_PIECE_MOVE_MINUSX:
|
|
|
|
case LC_PIECE_MOVE_PLUSY:
|
|
|
|
case LC_PIECE_MOVE_MINUSY:
|
|
|
|
case LC_PIECE_MOVE_PLUSZ:
|
|
|
|
case LC_PIECE_MOVE_MINUSZ:
|
|
|
|
case LC_PIECE_ROTATE_PLUSX:
|
|
|
|
case LC_PIECE_ROTATE_MINUSX:
|
|
|
|
case LC_PIECE_ROTATE_PLUSY:
|
|
|
|
case LC_PIECE_ROTATE_MINUSY:
|
|
|
|
case LC_PIECE_ROTATE_PLUSZ:
|
|
|
|
case LC_PIECE_ROTATE_MINUSZ:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 axis;
|
|
|
|
bool Rotate = id >= LC_PIECE_ROTATE_PLUSX && id <= LC_PIECE_ROTATE_MINUSZ;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Rotate)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_A)
|
|
|
|
axis[0] = axis[1] = axis[2] = m_nAngleSnap;
|
|
|
|
else
|
|
|
|
axis[0] = axis[1] = axis[2] = 1;
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float xy, z;
|
|
|
|
GetSnapDistance(&xy, &z);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
axis[0] = axis[1] = xy;
|
|
|
|
axis[2] = z;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((m_nSnap & LC_DRAW_SNAP_X) == 0)// || bControl)
|
|
|
|
axis[0] = 0.01f;
|
|
|
|
if ((m_nSnap & LC_DRAW_SNAP_Y) == 0)// || bControl)
|
|
|
|
axis[1] = 0.01f;
|
|
|
|
if ((m_nSnap & LC_DRAW_SNAP_Z) == 0)// || bControl)
|
|
|
|
axis[2] = 0.01f;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (id == LC_PIECE_MOVE_PLUSX || id == LC_PIECE_ROTATE_PLUSX)
|
|
|
|
axis = lcVector3(axis[0], 0, 0);
|
|
|
|
else if (id == LC_PIECE_MOVE_MINUSX || id == LC_PIECE_ROTATE_MINUSX)
|
|
|
|
axis = lcVector3(-axis[0], 0, 0);
|
|
|
|
else if (id == LC_PIECE_MOVE_PLUSY || id == LC_PIECE_ROTATE_PLUSY)
|
|
|
|
axis = lcVector3(0, axis[1], 0);
|
|
|
|
else if (id == LC_PIECE_MOVE_MINUSY || id == LC_PIECE_ROTATE_MINUSY)
|
|
|
|
axis = lcVector3(0, -axis[1], 0);
|
|
|
|
else if (id == LC_PIECE_MOVE_PLUSZ || id == LC_PIECE_ROTATE_PLUSZ)
|
|
|
|
axis = lcVector3(0, 0, axis[2]);
|
|
|
|
else if (id == LC_PIECE_MOVE_MINUSZ || id == LC_PIECE_ROTATE_MINUSZ)
|
|
|
|
axis = lcVector3(0, 0, -axis[2]);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((m_nSnap & LC_DRAW_MOVEAXIS) == 0)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: rewrite this
|
|
|
|
|
|
|
|
lcVector3 Pts[3] = { lcVector3(5.0f, 5.0f, 0.1f), lcVector3(10.0f, 5.0f, 0.1f), lcVector3(5.0f, 10.0f, 0.1f) };
|
|
|
|
gMainWindow->GetActiveView()->UnprojectPoints(Pts, 3);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float ax, ay;
|
|
|
|
lcVector3 vx((Pts[1][0] - Pts[0][0]), (Pts[1][1] - Pts[0][1]), 0);//Pts[1][2] - Pts[0][2] };
|
|
|
|
vx.Normalize();
|
|
|
|
lcVector3 x(1, 0, 0);
|
|
|
|
ax = acosf(lcDot(vx, x));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 vy((Pts[2][0] - Pts[0][0]), (Pts[2][1] - Pts[0][1]), 0);//Pts[2][2] - Pts[0][2] };
|
|
|
|
vy.Normalize();
|
|
|
|
lcVector3 y(0, -1, 0);
|
|
|
|
ay = acosf(lcDot(vy, y));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ax > 135)
|
|
|
|
axis[0] = -axis[0];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ay < 45)
|
|
|
|
axis[1] = -axis[1];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ax >= 45 && ax <= 135)
|
|
|
|
{
|
|
|
|
float tmp = axis[0];
|
|
|
|
|
|
|
|
ax = acosf(lcDot(vx, y));
|
|
|
|
if (ax > 90)
|
|
|
|
{
|
|
|
|
axis[0] = -axis[1];
|
|
|
|
axis[1] = tmp;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
axis[0] = axis[1];
|
|
|
|
axis[1] = -tmp;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Rotate)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 tmp;
|
|
|
|
RotateSelectedObjects(axis, tmp, true, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lcVector3 tmp;
|
|
|
|
MoveSelectedObjects(axis, tmp, false, true);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPoint(Rotate ? "Rotating" : "Moving");
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_MINIFIG_WIZARD:
|
|
|
|
{
|
|
|
|
lcMinifig Minifig;
|
|
|
|
int i;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_MINIFIG, &Minifig))
|
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SelectAndFocusNone(false);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (i = 0; i < LC_MFW_NUMITEMS; i++)
|
2014-04-10 06:46:48 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Minifig.Parts[i] == NULL)
|
|
|
|
continue;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* pPiece = new Piece(Minifig.Parts[i]);
|
|
|
|
|
|
|
|
lcVector4& Position = Minifig.Matrices[i][3];
|
|
|
|
lcVector4 Rotation = lcMatrix44ToAxisAngle(Minifig.Matrices[i]);
|
|
|
|
Rotation[3] *= LC_RTOD;
|
|
|
|
pPiece->Initialize(Position[0], Position[1], Position[2], m_nCurStep);
|
|
|
|
pPiece->SetColorIndex(Minifig.Colors[i]);
|
|
|
|
pPiece->CreateName(mPieces);
|
|
|
|
mPieces.Add(pPiece);
|
|
|
|
pPiece->SetSelected(true);
|
|
|
|
|
|
|
|
pPiece->ChangeKey(1, false, Rotation, LC_PK_ROTATION);
|
|
|
|
pPiece->UpdatePosition(m_nCurStep);
|
|
|
|
|
|
|
|
SystemPieceComboAdd(Minifig.Parts[i]->m_strDescription);
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
int Max = 0;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
{
|
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
|
|
|
|
if (strncmp(Group->m_strName, "Minifig #", 9) == 0)
|
|
|
|
if (sscanf(Group->m_strName, "Minifig #%d", &i) == 1)
|
|
|
|
if (i > Max)
|
|
|
|
Max = i;
|
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = AddGroup(NULL);
|
|
|
|
sprintf(Group->m_strName, "Minifig #%.2d", Max+1);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
2014-05-25 03:45:19 +02:00
|
|
|
Piece->SetGroup(Group);
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2011-09-07 23:06:51 +02:00
|
|
|
UpdateSelection();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2014-05-18 01:03:05 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Minifig");
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_ARRAY:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
int sel = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
sel++;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!sel)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("No pieces selected.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
2011-09-07 23:06:51 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArrayDialogOptions Options;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
memset(&Options, 0, sizeof(Options));
|
|
|
|
Options.Counts[0] = 10;
|
|
|
|
Options.Counts[1] = 1;
|
|
|
|
Options.Counts[2] = 1;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_PIECE_ARRAY, &Options))
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Options.Counts[0] * Options.Counts[1] * Options.Counts[2] < 2)
|
|
|
|
{
|
|
|
|
gMainWindow->DoMessageBox("Array only has 1 element or less, no pieces added.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
|
|
|
break;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ConvertFromUserUnits(Options.Offsets[0]);
|
|
|
|
ConvertFromUserUnits(Options.Offsets[1]);
|
|
|
|
ConvertFromUserUnits(Options.Offsets[2]);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcArray<Piece*> NewPieces;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int Step1 = 0; Step1 < Options.Counts[0]; Step1++)
|
|
|
|
{
|
|
|
|
for (int Step2 = 0; Step2 < Options.Counts[1]; Step2++)
|
|
|
|
{
|
|
|
|
for (int Step3 = 0; Step3 < Options.Counts[2]; Step3++)
|
|
|
|
{
|
|
|
|
if (Step1 == 0 && Step2 == 0 && Step3 == 0)
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMatrix44 ModelWorld;
|
|
|
|
lcVector3 Position;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 RotationAngles = Options.Rotations[0] * Step1 + Options.Rotations[1] * Step2 + Options.Rotations[2] * Step3;
|
|
|
|
lcVector3 Offset = Options.Offsets[0] * Step1 + Options.Offsets[1] * Step2 + Options.Offsets[2] * Step3;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* pPiece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!pPiece->IsSelected())
|
|
|
|
continue;
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (sel == 1)
|
|
|
|
{
|
|
|
|
ModelWorld = lcMul(pPiece->mModelWorld, lcMatrix44RotationX(RotationAngles[0] * LC_DTOR));
|
|
|
|
ModelWorld = lcMul(ModelWorld, lcMatrix44RotationY(RotationAngles[1] * LC_DTOR));
|
|
|
|
ModelWorld = lcMul(ModelWorld, lcMatrix44RotationZ(RotationAngles[2] * LC_DTOR));
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Position = pPiece->mPosition;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lcVector4 Center((bs[0] + bs[3]) / 2, (bs[1] + bs[4]) / 2, (bs[2] + bs[5]) / 2, 0.0f);
|
|
|
|
ModelWorld = pPiece->mModelWorld;
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ModelWorld.r[3] -= Center;
|
|
|
|
ModelWorld = lcMul(ModelWorld, lcMatrix44RotationX(RotationAngles[0] * LC_DTOR));
|
|
|
|
ModelWorld = lcMul(ModelWorld, lcMatrix44RotationY(RotationAngles[1] * LC_DTOR));
|
|
|
|
ModelWorld = lcMul(ModelWorld, lcMatrix44RotationZ(RotationAngles[2] * LC_DTOR));
|
|
|
|
ModelWorld.r[3] += Center;
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Position = lcVector3(ModelWorld.r[3].x, ModelWorld.r[3].y, ModelWorld.r[3].z);
|
|
|
|
}
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(ModelWorld);
|
|
|
|
AxisAngle[3] *= LC_RTOD;
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* NewPiece = new Piece(pPiece->mPieceInfo);
|
|
|
|
NewPieces.Add(NewPiece);
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
NewPiece->Initialize(Position[0] + Offset[0], Position[1] + Offset[1], Position[2] + Offset[2], m_nCurStep);
|
|
|
|
NewPiece->SetColorIndex(pPiece->mColorIndex);
|
|
|
|
NewPiece->ChangeKey(1, false, AxisAngle, LC_PK_ROTATION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-03 23:16:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < NewPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = NewPieces[PieceIdx];
|
|
|
|
Piece->CreateName(mPieces);
|
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
mPieces.Add(Piece);
|
|
|
|
}
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SelectAndFocusNone(true);
|
|
|
|
// gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
UpdateSelection();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2014-05-18 01:03:05 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Array");
|
|
|
|
} break;
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_GROUP:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
int i, Max = 0;
|
2014-05-18 01:03:05 +02:00
|
|
|
char name[65];
|
|
|
|
int Selected = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mPieces[PieceIdx]->IsSelected())
|
2014-04-10 06:46:48 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Selected++;
|
|
|
|
|
|
|
|
if (Selected > 1)
|
|
|
|
break;
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Selected)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->DoMessageBox("No pieces selected.", LC_MB_OK | LC_MB_ICONINFORMATION);
|
|
|
|
break;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
{
|
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
|
|
|
|
if (strncmp(Group->m_strName, "Group #", 7) == 0)
|
|
|
|
if (sscanf(Group->m_strName, "Group #%d", &i) == 1)
|
|
|
|
if (i > Max)
|
|
|
|
Max = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(name, "Group #%.2d", Max + 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_PIECE_GROUP, name))
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 20:23:09 +02:00
|
|
|
lcGroup* NewGroup = new lcGroup();
|
|
|
|
strcpy(NewGroup->m_strName, name);
|
|
|
|
mGroups.Add(NewGroup);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Piece->IsSelected())
|
2014-05-25 20:23:09 +02:00
|
|
|
{
|
|
|
|
lcGroup* Group = Piece->GetTopGroup();
|
|
|
|
|
|
|
|
if (!Group)
|
|
|
|
Piece->SetGroup(NewGroup);
|
|
|
|
else if (Group != NewGroup)
|
|
|
|
Group->mGroup = NewGroup;
|
|
|
|
}
|
2014-05-25 03:45:19 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
RemoveEmptyGroups();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Grouping");
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_UNGROUP:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcArray<lcGroup*> Groups;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcPiece* Piece = mPieces[PieceIdx];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = Piece->GetTopGroup();
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Groups.FindIndex(Group) == -1)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
mGroups.Remove(Group);
|
|
|
|
Groups.Add(Group);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2012-02-08 23:48:51 +01:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcPiece* Piece = mPieces[PieceIdx];
|
|
|
|
lcGroup* Group = Piece->GetGroup();
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Groups.FindIndex(Group) != -1)
|
|
|
|
Piece->SetGroup(NULL);
|
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
{
|
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
|
|
|
|
if (Groups.FindIndex(Group->mGroup) != -1)
|
|
|
|
Group->mGroup = NULL;
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
Groups.DeleteAll();
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RemoveEmptyGroups();
|
2013-08-09 06:57:18 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPoint("Ungrouping");
|
2013-08-09 06:57:18 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_GROUP_ADD:
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Group* pGroup = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
pGroup = Piece->GetTopGroup();
|
|
|
|
if (pGroup != NULL)
|
|
|
|
break;
|
|
|
|
}
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pGroup != NULL)
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused())
|
|
|
|
{
|
|
|
|
Piece->SetGroup(pGroup);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RemoveEmptyGroups();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Grouping");
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_GROUP_REMOVE:
|
|
|
|
{
|
2014-05-01 16:55:12 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused())
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-25 20:23:09 +02:00
|
|
|
Piece->SetGroup(NULL);
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RemoveEmptyGroups();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Ungrouping");
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_PIECE_GROUP_EDIT:
|
|
|
|
{
|
|
|
|
lcEditGroupsDialogOptions Options;
|
|
|
|
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
Options.PieceParents.Add(mPieces[PieceIdx]->GetGroup());
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
Options.GroupParents.Add(mGroups[GroupIdx]->mGroup);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!gMainWindow->DoDialog(LC_DIALOG_EDIT_GROUPS, &Options))
|
|
|
|
break;
|
|
|
|
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
mPieces[PieceIdx]->SetGroup(Options.PieceParents[PieceIdx]);
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
mGroups[GroupIdx]->mGroup = Options.GroupParents[GroupIdx];
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
RemoveEmptyGroups();
|
|
|
|
SelectAndFocusNone(false);
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-01 16:55:12 +02:00
|
|
|
UpdateSelection();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2014-05-01 16:55:12 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPoint("Editing");
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_HIDE_SELECTED:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if (Piece->IsSelected())
|
2014-01-30 04:13:34 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->SetHidden(true);
|
|
|
|
Piece->SetSelected(false);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateFocusObject(NULL);
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_PIECE_HIDE_UNSELECTED:
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-01-30 04:13:34 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Piece->IsSelected())
|
|
|
|
Piece->SetHidden(true);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
} break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_UNHIDE_ALL:
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
mPieces[PieceIdx]->SetHidden(false);
|
2014-01-30 04:13:34 +01:00
|
|
|
UpdateSelection();
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_SHOW_EARLIER:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
bool redraw = false;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
2014-04-10 06:46:48 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
unsigned char t = Piece->GetStepShow();
|
|
|
|
if (t > 1)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
redraw = true;
|
|
|
|
Piece->SetStepShow(t-1);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (redraw)
|
|
|
|
{
|
2011-09-07 23:06:51 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPoint("Modifying");
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_SHOW_LATER:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
bool redraw = false;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if (Piece->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
unsigned char t = Piece->GetStepShow();
|
|
|
|
if (t < 255)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
redraw = true;
|
|
|
|
Piece->SetStepShow(t+1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (t == m_nCurStep)
|
|
|
|
Piece->SetSelected(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (redraw)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Modifying");
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
UpdateSelection ();
|
|
|
|
}
|
|
|
|
} break;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_PREFERENCES:
|
|
|
|
{
|
|
|
|
g_App->ShowPreferencesDialog();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int i = 0; i < Views.GetSize (); i++)
|
|
|
|
{
|
|
|
|
Views[i]->MakeCurrent();
|
|
|
|
RenderInitialize(); // TODO: get rid of RenderInitialize(), most of it can be done once per frame
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_ZOOM_IN:
|
|
|
|
{
|
|
|
|
ZoomActiveView(-1);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_ZOOM_OUT:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
ZoomActiveView(1);
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_VIEW_ZOOM_EXTENTS:
|
|
|
|
{
|
|
|
|
int FirstView, LastView;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: Find a way to let users zoom extents all views
|
|
|
|
// if (Sys_KeyDown(KEY_CONTROL))
|
|
|
|
// {
|
|
|
|
// FirstView = 0;
|
|
|
|
// LastView = m_ViewList.GetSize();
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
{
|
|
|
|
FirstView = gMainWindow->GetViews().FindIndex(gMainWindow->GetActiveView());
|
|
|
|
LastView = FirstView + 1;
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ZoomExtents(FirstView, LastView);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_VIEW_LOOK_AT:
|
|
|
|
{
|
|
|
|
lcVector3 Center;
|
|
|
|
|
|
|
|
if (!GetSelectionCenter(Center))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-18 01:03:05 +02:00
|
|
|
mPieces[PieceIdx]->CompareBoundingBox(bs);
|
2013-12-17 23:23:41 +01:00
|
|
|
|
|
|
|
Center = lcVector3((bs[0] + bs[3]) * 0.5f, (bs[1] + bs[4]) * 0.5f, (bs[2] + bs[5]) * 0.5f);
|
|
|
|
}
|
|
|
|
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->Center(Center, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2013-12-17 23:23:41 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_NEXT:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nCurStep++;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
CalculateStep();
|
|
|
|
UpdateSelection();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_PREVIOUS:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nCurStep--;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
CalculateStep();
|
|
|
|
UpdateSelection();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_FIRST:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nCurStep = 1;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
CalculateStep();
|
|
|
|
UpdateSelection();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_LAST:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nCurStep = GetLastStep ();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
CalculateStep();
|
|
|
|
UpdateSelection();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-01-30 04:13:34 +01:00
|
|
|
gMainWindow->UpdateTime(m_nCurStep, 255);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_INSERT:
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
Piece->InsertTime(m_nCurStep, 1);
|
|
|
|
if (Piece->IsSelected() && !Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->SetSelected(false);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
2014-01-30 04:13:34 +01:00
|
|
|
mCameras[CameraIdx]->InsertTime(m_nCurStep, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-09 00:34:50 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
mLights[LightIdx]->InsertTime(m_nCurStep, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-01-30 04:13:34 +01:00
|
|
|
CheckPoint("Adding Step");
|
2012-08-22 03:13:32 +02:00
|
|
|
CalculateStep();
|
2014-05-01 16:55:12 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2012-08-22 03:13:32 +02:00
|
|
|
UpdateSelection();
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_DELETE:
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
2014-04-10 06:46:48 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
|
|
|
Piece->RemoveTime(m_nCurStep, 1);
|
|
|
|
if (Piece->IsSelected() && !Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->SetSelected(false);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
2014-01-30 04:13:34 +01:00
|
|
|
mCameras[CameraIdx]->RemoveTime(m_nCurStep, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-04-09 00:34:50 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
mLights[LightIdx]->RemoveTime(m_nCurStep, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-01 16:55:12 +02:00
|
|
|
SetModifiedFlag(true);
|
2014-01-30 04:13:34 +01:00
|
|
|
CheckPoint("Removing Step");
|
2012-08-22 03:13:32 +02:00
|
|
|
CalculateStep();
|
2014-05-01 16:55:12 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2012-08-22 03:13:32 +02:00
|
|
|
UpdateSelection();
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_FRONT:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_FRONT, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_BACK:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_BACK, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_TOP:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_TOP, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_BOTTOM:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_BOTTOM, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_LEFT:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_LEFT, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_RIGHT:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_RIGHT, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2012-08-20 06:05:56 +02:00
|
|
|
case LC_VIEW_VIEWPOINT_HOME:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->SetViewpoint(LC_VIEWPOINT_HOME, m_nCurStep, gMainWindow->GetAddKeys());
|
2013-08-09 06:57:18 +02:00
|
|
|
HandleCommand(LC_VIEW_ZOOM_EXTENTS);
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_CAMERA_NONE:
|
|
|
|
case LC_VIEW_CAMERA1:
|
|
|
|
case LC_VIEW_CAMERA2:
|
|
|
|
case LC_VIEW_CAMERA3:
|
|
|
|
case LC_VIEW_CAMERA4:
|
|
|
|
case LC_VIEW_CAMERA5:
|
|
|
|
case LC_VIEW_CAMERA6:
|
|
|
|
case LC_VIEW_CAMERA7:
|
|
|
|
case LC_VIEW_CAMERA8:
|
|
|
|
case LC_VIEW_CAMERA9:
|
|
|
|
case LC_VIEW_CAMERA10:
|
|
|
|
case LC_VIEW_CAMERA11:
|
|
|
|
case LC_VIEW_CAMERA12:
|
|
|
|
case LC_VIEW_CAMERA13:
|
|
|
|
case LC_VIEW_CAMERA14:
|
|
|
|
case LC_VIEW_CAMERA15:
|
|
|
|
case LC_VIEW_CAMERA16:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
View* ActiveView = gMainWindow->GetActiveView();
|
|
|
|
lcCamera* Camera = NULL;
|
2012-11-15 02:14:35 +01:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
if (id == LC_VIEW_CAMERA_NONE)
|
2012-11-15 02:14:35 +01:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
Camera = ActiveView->mCamera;
|
2012-11-15 02:14:35 +01:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
if (!Camera->IsSimple())
|
2012-11-15 02:14:35 +01:00
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
ActiveView->SetCamera(Camera, true);
|
|
|
|
Camera = ActiveView->mCamera;
|
2012-11-15 02:14:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
if (id - LC_VIEW_CAMERA1 < mCameras.GetSize())
|
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
Camera = mCameras[id - LC_VIEW_CAMERA1];
|
|
|
|
ActiveView->SetCamera(Camera, false);
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
2012-11-15 02:14:35 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateCurrentCamera(mCameras.FindIndex(ActiveView->mCamera));
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_VIEW_CAMERA_RESET:
|
|
|
|
{
|
2014-05-03 23:16:48 +02:00
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
|
|
|
|
Views[ViewIdx]->SetDefaultCamera();
|
2012-02-05 03:50:57 +01:00
|
|
|
|
2012-08-22 03:13:32 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
delete mCameras[CameraIdx];
|
|
|
|
mCameras.RemoveAll();
|
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Reset Cameras");
|
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_HELP_HOMEPAGE:
|
|
|
|
g_App->OpenURL("http://www.leocad.org/");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_HELP_EMAIL:
|
|
|
|
g_App->OpenURL("mailto:leozide@gmail.com?subject=LeoCAD");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_HELP_UPDATES:
|
|
|
|
gMainWindow->DoDialog(LC_DIALOG_CHECK_UPDATES, NULL);
|
|
|
|
break;
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
case LC_HELP_ABOUT:
|
|
|
|
{
|
2013-08-09 06:57:18 +02:00
|
|
|
String Info;
|
|
|
|
char Text[256];
|
|
|
|
|
2014-05-03 23:16:48 +02:00
|
|
|
gMainWindow->GetActiveView()->MakeCurrent();
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
GLint Red, Green, Blue, Alpha, Depth, Stencil;
|
|
|
|
GLboolean DoubleBuffer, RGBA;
|
|
|
|
|
|
|
|
glGetIntegerv(GL_RED_BITS, &Red);
|
|
|
|
glGetIntegerv(GL_GREEN_BITS, &Green);
|
|
|
|
glGetIntegerv(GL_BLUE_BITS, &Blue);
|
|
|
|
glGetIntegerv(GL_ALPHA_BITS, &Alpha);
|
|
|
|
glGetIntegerv(GL_DEPTH_BITS, &Depth);
|
|
|
|
glGetIntegerv(GL_STENCIL_BITS, &Stencil);
|
|
|
|
glGetBooleanv(GL_DOUBLEBUFFER, &DoubleBuffer);
|
|
|
|
glGetBooleanv(GL_RGBA_MODE, &RGBA);
|
|
|
|
|
|
|
|
Info = "OpenGL Version ";
|
|
|
|
Info += (const char*)glGetString(GL_VERSION);
|
|
|
|
Info += "\n";
|
|
|
|
Info += (const char*)glGetString(GL_RENDERER);
|
|
|
|
Info += " - ";
|
|
|
|
Info += (const char*)glGetString(GL_VENDOR);
|
|
|
|
sprintf(Text, "\n\nColor Buffer: %d bits %s %s", Red + Green + Blue + Alpha, RGBA ? "RGBA" : "indexed", DoubleBuffer ? "double buffered" : "");
|
|
|
|
Info += Text;
|
|
|
|
sprintf(Text, "\nDepth Buffer: %d bits", Depth);
|
|
|
|
Info += Text;
|
|
|
|
sprintf(Text, "\nStencil Buffer: %d bits", Stencil);
|
|
|
|
Info += Text;
|
|
|
|
Info += "\nGL_ARB_vertex_buffer_object extension: ";
|
|
|
|
Info += GL_HasVertexBufferObject() ? "supported" : "not supported";
|
|
|
|
Info += "\nGL_ARB_framebuffer_object extension: ";
|
2014-01-13 01:29:12 +01:00
|
|
|
Info += GL_HasFramebufferObjectARB() ? "supported" : "not supported";
|
|
|
|
Info += "\nGL_EXT_framebuffer_object extension: ";
|
|
|
|
Info += GL_HasFramebufferObjectEXT() ? "supported" : "not supported";
|
2013-08-31 23:58:47 +02:00
|
|
|
Info += "\nGL_EXT_texture_filter_anisotropic extension: ";
|
|
|
|
if (GL_SupportsAnisotropic)
|
|
|
|
{
|
|
|
|
sprintf(Text, "supported (max %d)", (int)GL_MaxAnisotropy);
|
|
|
|
Info += Text;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Info += "not supported";
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
gMainWindow->DoDialog(LC_DIALOG_ABOUT, (char*)Info);
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_VIEW_TIME_ADD_KEYS:
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->SetAddKeys(!gMainWindow->GetAddKeys());
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_SNAP_X:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_X)
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_X;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_SNAP_X;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_SNAP_Y:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_Y)
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_Y;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_SNAP_Y;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_SNAP_Z:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_Z)
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_Z;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_SNAP_Z;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_SNAP_ALL:
|
2012-02-10 00:51:14 +01:00
|
|
|
m_nSnap |= LC_DRAW_SNAP_XYZ;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2011-09-07 23:06:51 +02:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_SNAP_NONE:
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_XYZ;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_SNAP_TOGGLE:
|
2014-01-30 04:13:34 +01:00
|
|
|
if ((m_nSnap & LC_DRAW_SNAP_XYZ) == LC_DRAW_SNAP_XYZ)
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_XYZ;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_SNAP_XYZ;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_LOCK_X:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_X)
|
|
|
|
m_nSnap &= ~LC_DRAW_LOCK_X;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_LOCK_X;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_LOCK_Y:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Y)
|
|
|
|
m_nSnap &= ~LC_DRAW_LOCK_Y;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_LOCK_Y;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_LOCK_Z:
|
2014-01-30 04:13:34 +01:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Z)
|
|
|
|
m_nSnap &= ~LC_DRAW_LOCK_Z;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_LOCK_Z;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_LOCK_NONE:
|
2014-01-30 04:13:34 +01:00
|
|
|
m_nSnap &= ~LC_DRAW_LOCK_XYZ;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
|
|
|
case LC_EDIT_LOCK_TOGGLE:
|
2014-01-30 04:13:34 +01:00
|
|
|
if ((m_nSnap & LC_DRAW_LOCK_XYZ) == LC_DRAW_LOCK_XYZ)
|
|
|
|
m_nSnap &= ~LC_DRAW_LOCK_XYZ;
|
|
|
|
else
|
|
|
|
m_nSnap |= LC_DRAW_LOCK_XYZ;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateLockSnap(m_nSnap);
|
2014-01-30 04:13:34 +01:00
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_SNAP_MOVE_XY0:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY1:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY2:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY3:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY4:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY5:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY6:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY7:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY8:
|
|
|
|
case LC_EDIT_SNAP_MOVE_XY9:
|
|
|
|
{
|
|
|
|
m_nMoveSnap = (id - LC_EDIT_SNAP_MOVE_XY0) | (m_nMoveSnap & ~0xff);
|
|
|
|
if (id != LC_EDIT_SNAP_MOVE_XY0)
|
2012-02-10 00:51:14 +01:00
|
|
|
m_nSnap |= LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y;
|
|
|
|
else
|
|
|
|
m_nSnap &= ~(LC_DRAW_SNAP_X | LC_DRAW_SNAP_Y);
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateSnap();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_SNAP_MOVE_Z0:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z1:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z2:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z3:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z4:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z5:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z6:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z7:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z8:
|
|
|
|
case LC_EDIT_SNAP_MOVE_Z9:
|
|
|
|
{
|
|
|
|
m_nMoveSnap = (((id - LC_EDIT_SNAP_MOVE_Z0) << 8) | (m_nMoveSnap & ~0xff00));
|
|
|
|
if (id != LC_EDIT_SNAP_MOVE_Z0)
|
2012-02-10 00:51:14 +01:00
|
|
|
m_nSnap |= LC_DRAW_SNAP_Z;
|
|
|
|
else
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_Z;
|
2013-08-09 06:57:18 +02:00
|
|
|
gMainWindow->UpdateSnap();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_SNAP_ANGLE:
|
|
|
|
if (m_nSnap & LC_DRAW_SNAP_A)
|
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_A;
|
|
|
|
else
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2012-02-10 00:51:14 +01:00
|
|
|
m_nSnap |= LC_DRAW_SNAP_A;
|
2013-08-09 06:57:18 +02:00
|
|
|
m_nAngleSnap = lcMax(1, m_nAngleSnap);
|
|
|
|
}
|
|
|
|
gMainWindow->UpdateSnap();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_EDIT_SNAP_ANGLE0:
|
|
|
|
case LC_EDIT_SNAP_ANGLE1:
|
|
|
|
case LC_EDIT_SNAP_ANGLE2:
|
|
|
|
case LC_EDIT_SNAP_ANGLE3:
|
|
|
|
case LC_EDIT_SNAP_ANGLE4:
|
|
|
|
case LC_EDIT_SNAP_ANGLE5:
|
|
|
|
case LC_EDIT_SNAP_ANGLE6:
|
|
|
|
case LC_EDIT_SNAP_ANGLE7:
|
|
|
|
case LC_EDIT_SNAP_ANGLE8:
|
|
|
|
case LC_EDIT_SNAP_ANGLE9:
|
|
|
|
{
|
|
|
|
const int Angles[] = { 0, 1, 5, 10, 15, 30, 45, 60, 90, 180 };
|
|
|
|
|
|
|
|
if (id == LC_EDIT_SNAP_ANGLE0)
|
2012-02-10 00:51:14 +01:00
|
|
|
m_nSnap &= ~LC_DRAW_SNAP_A;
|
2013-08-09 06:57:18 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_nSnap |= LC_DRAW_SNAP_A;
|
|
|
|
m_nAngleSnap = Angles[id - LC_EDIT_SNAP_ANGLE0];
|
|
|
|
}
|
|
|
|
gMainWindow->UpdateSnap();
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2013-08-09 06:57:18 +02:00
|
|
|
case LC_EDIT_TRANSFORM:
|
|
|
|
TransformSelectedObjects((LC_TRANSFORM_TYPE)mTransformType, gMainWindow->GetTransformAmount());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION:
|
|
|
|
case LC_EDIT_TRANSFORM_RELATIVE_TRANSLATION:
|
|
|
|
case LC_EDIT_TRANSFORM_ABSOLUTE_ROTATION:
|
|
|
|
case LC_EDIT_TRANSFORM_RELATIVE_ROTATION:
|
|
|
|
mTransformType = id - LC_EDIT_TRANSFORM_ABSOLUTE_TRANSLATION;
|
|
|
|
gMainWindow->UpdateTransformType(mTransformType);
|
|
|
|
break;
|
|
|
|
|
2011-09-07 23:06:51 +02:00
|
|
|
case LC_EDIT_ACTION_SELECT:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_SELECT);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
case LC_EDIT_ACTION_INSERT:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_INSERT);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
case LC_EDIT_ACTION_LIGHT:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_LIGHT);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
case LC_EDIT_ACTION_SPOTLIGHT:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_SPOTLIGHT);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
|
|
|
case LC_EDIT_ACTION_CAMERA:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_CAMERA);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_MOVE:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_MOVE);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_ROTATE:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ROTATE);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_DELETE:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ERASER);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_PAINT:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_PAINT);
|
|
|
|
break;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_ZOOM:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ZOOM);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_ZOOM_REGION:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ZOOM_REGION);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_PAN:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_PAN);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_ROTATE_VIEW:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ROTATE_VIEW);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_ACTION_ROLL:
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_ROLL);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_EDIT_CANCEL:
|
|
|
|
{
|
|
|
|
if (m_nTracking != LC_TRACK_NONE)
|
|
|
|
StopTracking(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
else
|
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
SelectAndFocusNone(false);
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdateFocusObject(NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_NUM_COMMANDS:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Remove unused groups
|
|
|
|
void Project::RemoveEmptyGroups()
|
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
bool Removed;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
do
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
Removed = false;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize();)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
|
|
|
int Ref = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
if (mPieces[PieceIdx]->GetGroup() == Group)
|
|
|
|
Ref++;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++)
|
|
|
|
if (mGroups[ParentIdx]->mGroup == Group)
|
|
|
|
Ref++;
|
2014-05-18 01:03:05 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (Ref > 1)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
GroupIdx++;
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-25 03:45:19 +02:00
|
|
|
|
|
|
|
if (Ref != 0)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
lcPiece* Piece = mPieces[PieceIdx];
|
|
|
|
|
|
|
|
if (Piece->GetGroup() == Group)
|
2014-05-18 01:03:05 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
Piece->SetGroup(Group->mGroup);
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
|
|
|
}
|
2014-05-25 03:45:19 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int ParentIdx = 0; ParentIdx < mGroups.GetSize(); ParentIdx++)
|
|
|
|
{
|
|
|
|
if (mGroups[ParentIdx]->mGroup == Group)
|
|
|
|
{
|
|
|
|
mGroups[ParentIdx]->mGroup = Group->mGroup;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
mGroups.RemoveIndex(GroupIdx);
|
|
|
|
delete Group;
|
|
|
|
Removed = true;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-25 03:45:19 +02:00
|
|
|
while (Removed);
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* Project::AddGroup(lcGroup* Parent)
|
2012-08-13 02:28:35 +02:00
|
|
|
{
|
2014-05-25 03:45:19 +02:00
|
|
|
lcGroup* NewGroup = new lcGroup();
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
int i, Max = 0;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
|
|
|
|
{
|
|
|
|
lcGroup* Group = mGroups[GroupIdx];
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
if (strncmp(Group->m_strName, "Group #", 7) == 0)
|
|
|
|
if (sscanf(Group->m_strName, "Group #%d", &i) == 1)
|
|
|
|
if (i > Max)
|
|
|
|
Max = i;
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
sprintf(NewGroup->m_strName, "Group #%.2d", Max + 1);
|
|
|
|
mGroups.Add(NewGroup);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
NewGroup->mGroup = Parent;
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-25 03:45:19 +02:00
|
|
|
return NewGroup;
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2012-08-22 03:13:32 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::SelectAndFocusNone(bool FocusOnly)
|
|
|
|
{
|
|
|
|
if (FocusOnly)
|
|
|
|
{
|
|
|
|
Object* FocusObject = GetFocusObject();
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (FocusObject)
|
|
|
|
FocusObject->SetFocused(FocusObject->GetFocusSection(), false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
mPieces[PieceIdx]->SetSelected(false);
|
2014-04-09 00:34:50 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
mCameras[CameraIdx]->SetSelected(false);
|
|
|
|
|
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
mLights[LightIdx]->SetSelected(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::SelectGroup(Group* TopGroup, bool Select)
|
|
|
|
{
|
|
|
|
if (!TopGroup)
|
|
|
|
return;
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Piece->IsSelected() && Piece->IsVisible(m_nCurStep) && (Piece->GetTopGroup() == TopGroup))
|
|
|
|
Piece->SetSelected(Select);
|
|
|
|
}
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::FocusOrDeselectObject(const lcObjectSection& ObjectSection)
|
|
|
|
{
|
|
|
|
Object* FocusObject = GetFocusObject();
|
|
|
|
Object* Object = ObjectSection.Object;
|
|
|
|
lcuint32 Section = ObjectSection.Section;
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Object)
|
|
|
|
{
|
|
|
|
bool WasSelected = Object->IsSelected();
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Object->IsFocused(Section))
|
2012-08-13 02:28:35 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (FocusObject)
|
|
|
|
FocusObject->SetFocused(FocusObject->GetFocusSection(), false);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Object->SetFocused(Section, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Object->SetSelected(Section, false);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool IsSelected = Object->IsSelected();
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Object->IsPiece() && (WasSelected != IsSelected))
|
|
|
|
SelectGroup(((Piece*)Object)->GetTopGroup(), IsSelected);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (FocusObject)
|
|
|
|
FocusObject->SetFocused(FocusObject->GetFocusSection(), false);
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ClearSelectionAndSetFocus(Object* Object, lcuint32 Section)
|
|
|
|
{
|
|
|
|
SelectAndFocusNone(false);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Object)
|
|
|
|
{
|
|
|
|
Object->SetFocused(Section, true);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Object->IsPiece())
|
|
|
|
SelectGroup(((Piece*)Object)->GetTopGroup(), true);
|
|
|
|
}
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdateFocusObject(Object);
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::SetSelection(const lcArray<lcObjectSection>& ObjectSections)
|
|
|
|
{
|
|
|
|
SelectAndFocusNone(false);
|
|
|
|
AddToSelection(ObjectSections);
|
|
|
|
}
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::AddToSelection(const lcArray<lcObjectSection>& ObjectSections)
|
|
|
|
{
|
|
|
|
for (int ObjectIdx = 0; ObjectIdx < ObjectSections.GetSize(); ObjectIdx++)
|
|
|
|
{
|
|
|
|
lcObject* Object = ObjectSections[ObjectIdx].Object;
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool WasSelected = Object->IsSelected();
|
|
|
|
Object->SetSelected(ObjectSections[ObjectIdx].Section, true);
|
2012-08-13 02:28:35 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!WasSelected && Object->GetType() == LC_OBJECT_PIECE)
|
|
|
|
SelectGroup(((Piece*)Object)->GetTopGroup(), true);
|
2012-08-13 02:28:35 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
2012-08-13 02:28:35 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::GetSelectionCenter(lcVector3& Center) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
bool Selected = false;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
Selected = true;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Center = lcVector3((bs[0] + bs[3]) * 0.5f, (bs[1] + bs[4]) * 0.5f, (bs[2] + bs[5]) * 0.5f);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return Selected;
|
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Project::GetFocusOrSelectionCenter() const
|
|
|
|
{
|
|
|
|
lcVector3 Center;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (GetFocusPosition(Center))
|
|
|
|
return Center;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GetSelectionCenter(Center);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return Center;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ConvertToUserUnits(lcVector3& Value) const
|
|
|
|
{
|
|
|
|
Value /= 0.04f;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ConvertFromUserUnits(lcVector3& Value) const
|
|
|
|
{
|
|
|
|
Value *= 0.04f;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::GetFocusPosition(lcVector3& Position) const
|
|
|
|
{
|
|
|
|
Object* FocusObject = GetFocusObject();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (FocusObject)
|
|
|
|
{
|
|
|
|
Position = FocusObject->GetSectionPosition(FocusObject->GetFocusSection());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Position = lcVector3(0.0f, 0.0f, 0.0f);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Returns the object that currently has focus.
|
|
|
|
Object* Project::GetFocusObject() const
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsFocused())
|
|
|
|
return Piece;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* Camera = mCameras[CameraIdx];
|
|
|
|
|
|
|
|
if (Camera->IsFocused())
|
|
|
|
return Camera;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
{
|
|
|
|
Light* Light = mLights[LightIdx];
|
|
|
|
|
|
|
|
if (Light->IsFocused())
|
|
|
|
return Light;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Project::AnyObjectsSelected(bool PiecesOnly) const
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
if (mPieces[PieceIdx]->IsSelected())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!PiecesOnly)
|
|
|
|
{
|
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
if (mCameras[CameraIdx]->IsSelected())
|
|
|
|
return true;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (mLights[LightIdx]->IsSelected())
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return false;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Find a good starting position/orientation relative to an existing piece.
|
|
|
|
void Project::GetPieceInsertPosition(Piece* OffsetPiece, lcVector3& Position, lcVector4& Rotation)
|
|
|
|
{
|
|
|
|
lcVector3 Dist(0, 0, OffsetPiece->mPieceInfo->m_fDimensions[2] - m_pCurPiece->m_fDimensions[5]);
|
|
|
|
SnapVector(Dist);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Position = lcMul31(Dist, OffsetPiece->mModelWorld);
|
|
|
|
Rotation = OffsetPiece->mRotation;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Try to find a good starting position/orientation for a new piece.
|
|
|
|
void Project::GetPieceInsertPosition(View* view, lcVector3& Position, lcVector4& Rotation)
|
|
|
|
{
|
|
|
|
// Check if the mouse is over a piece.
|
|
|
|
Piece* HitPiece = (Piece*)view->FindObjectUnderPointer(true).Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (HitPiece)
|
|
|
|
{
|
|
|
|
GetPieceInsertPosition(HitPiece, Position, Rotation);
|
|
|
|
return;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Try to hit the base grid.
|
|
|
|
lcVector3 ClickPoints[2] = { lcVector3((float)view->mInputState.x, (float)view->mInputState.y, 0.0f), lcVector3((float)view->mInputState.x, (float)view->mInputState.y, 1.0f) };
|
|
|
|
view->UnprojectPoints(ClickPoints, 2);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Intersection;
|
|
|
|
if (lcLinePlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, m_pCurPiece->m_fDimensions[5])))
|
|
|
|
{
|
|
|
|
SnapVector(Intersection);
|
|
|
|
Position = Intersection;
|
|
|
|
Rotation = lcVector4(0, 0, 1, 0);
|
|
|
|
return;
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Couldn't find a good position, so just place the piece somewhere near the camera.
|
|
|
|
Position = view->UnprojectPoint(lcVector3((float)view->mInputState.x, (float)view->mInputState.y, 0.9f));
|
|
|
|
Rotation = lcVector4(0, 0, 1, 0);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::RayTest(lcObjectRayTest& ObjectRayTest) const
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->RayTest(ObjectRayTest);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ObjectRayTest.PiecesOnly)
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* Camera = mCameras[CameraIdx];
|
2014-05-03 03:22:24 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera != ObjectRayTest.ViewCamera && Camera->IsVisible())
|
|
|
|
Camera->RayTest(ObjectRayTest);
|
|
|
|
}
|
2014-05-03 03:22:24 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (mLights[LightIdx]->IsVisible())
|
|
|
|
mLights[LightIdx]->RayTest(ObjectRayTest);
|
|
|
|
}
|
2014-05-03 03:22:24 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BoxTest(lcObjectBoxTest& ObjectBoxTest) const
|
|
|
|
{
|
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsVisible(m_nCurStep))
|
|
|
|
Piece->BoxTest(ObjectBoxTest);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* Camera = mCameras[CameraIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera != ObjectBoxTest.ViewCamera && Camera->IsVisible())
|
|
|
|
Camera->BoxTest(ObjectBoxTest);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
if (mLights[LightIdx]->IsVisible())
|
|
|
|
mLights[LightIdx]->BoxTest(ObjectBoxTest);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::StopTracking(bool bAccept)
|
|
|
|
{
|
|
|
|
if (m_nTracking == LC_TRACK_NONE)
|
|
|
|
return false;
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
View* ActiveView = gMainWindow->GetActiveView();
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
m_nTracking = LC_TRACK_NONE;
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (bAccept && mDropPiece)
|
|
|
|
{
|
|
|
|
int x = m_nDownX;
|
|
|
|
int y = m_nDownY;
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((x > 0) && (x < ActiveView->mWidth) && (y > 0) && (y < ActiveView->mHeight))
|
2013-08-09 06:57:18 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Pos;
|
|
|
|
lcVector4 Rot;
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
GetPieceInsertPosition(ActiveView, Pos, Rot);
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* pPiece = new Piece(mDropPiece);
|
|
|
|
pPiece->Initialize(Pos[0], Pos[1], Pos[2], m_nCurStep);
|
|
|
|
pPiece->SetColorIndex(gMainWindow->mColorIndex);
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pPiece->ChangeKey(m_nCurStep, false, Rot, LC_PK_ROTATION);
|
|
|
|
pPiece->UpdatePosition(m_nCurStep);
|
|
|
|
|
|
|
|
pPiece->CreateName(mPieces);
|
|
|
|
mPieces.Add(pPiece);
|
|
|
|
SystemPieceComboAdd(mDropPiece->m_strDescription);
|
|
|
|
ClearSelectionAndSetFocus(pPiece, LC_PIECE_SECTION_POSITION);
|
|
|
|
|
|
|
|
if (mDropPiece)
|
|
|
|
{
|
|
|
|
mDropPiece->Release();
|
|
|
|
mDropPiece = NULL;
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Inserting");
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
|
|
|
}
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (mDropPiece)
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
mDropPiece->Release();
|
|
|
|
mDropPiece = NULL;
|
2013-08-09 06:57:18 +02:00
|
|
|
}
|
2012-02-01 03:08:30 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return true;
|
2013-12-17 03:43:16 +01:00
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::StartTracking(int mode)
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
m_nTracking = mode;
|
2013-12-17 03:43:16 +01:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::GetSnapIndex(int* SnapXY, int* SnapZ, int* SnapAngle) const
|
2013-12-17 03:43:16 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
if (SnapXY)
|
|
|
|
*SnapXY = (m_nMoveSnap & 0xff);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (SnapZ)
|
|
|
|
*SnapZ = ((m_nMoveSnap >> 8) & 0xff);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (SnapAngle)
|
|
|
|
{
|
|
|
|
if (m_nSnap & LC_DRAW_SNAP_A)
|
|
|
|
{
|
|
|
|
int Angles[] = { 0, 1, 5, 10, 15, 30, 45, 60, 90, 180 };
|
|
|
|
*SnapAngle = -1;
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (unsigned int i = 0; i < sizeof(Angles)/sizeof(Angles[0]); i++)
|
|
|
|
{
|
|
|
|
if (m_nAngleSnap == Angles[i])
|
|
|
|
{
|
|
|
|
*SnapAngle = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*SnapAngle = 0;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::GetSnapDistance(float* SnapXY, float* SnapZ) const
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
const float SnapXYTable[] = { 0.01f, 0.04f, 0.2f, 0.32f, 0.4f, 0.8f, 1.6f, 2.4f, 3.2f, 6.4f };
|
|
|
|
const float SnapZTable[] = { 0.01f, 0.04f, 0.2f, 0.32f, 0.4f, 0.8f, 0.96f, 1.92f, 3.84f, 7.68f };
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int SXY, SZ;
|
|
|
|
GetSnapIndex(&SXY, &SZ, NULL);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SXY = lcMin(SXY, 9);
|
|
|
|
SZ = lcMin(SZ, 9);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
*SnapXY = SnapXYTable[SXY];
|
|
|
|
*SnapZ = SnapZTable[SZ];
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::GetSnapText(char* SnapXY, char* SnapZ, char* SnapAngle) const
|
|
|
|
{
|
|
|
|
const char* SnapXYText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "2S", "3S", "4S", "8S" };
|
|
|
|
const char* SnapZText[] = { "0", "1/20S", "1/4S", "1F", "1/2S", "1S", "1B", "2B", "4B", "8B" };
|
|
|
|
const char* SnapAngleText[] = { "0", "1", "5", "10", "15", "30", "45", "60", "90", "180" };
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int SXY, SZ, SA;
|
|
|
|
GetSnapIndex(&SXY, &SZ, &SA);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SXY = lcMin(SXY, 9);
|
|
|
|
SZ = lcMin(SZ, 9);
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
strcpy(SnapXY, SnapXYText[SXY]);
|
|
|
|
strcpy(SnapZ, SnapZText[SZ]);
|
|
|
|
strcpy(SnapAngle, SnapAngleText[SA]);
|
|
|
|
}
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::SnapVector(lcVector3& Delta, lcVector3& Leftover) const
|
|
|
|
{
|
|
|
|
float SnapXY, SnapZ;
|
|
|
|
GetSnapDistance(&SnapXY, &SnapZ);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_X)
|
|
|
|
{
|
|
|
|
int i = (int)(Delta[0] / SnapXY);
|
|
|
|
Leftover[0] = Delta[0] - (SnapXY * i);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Leftover[0] > SnapXY / 2)
|
|
|
|
{
|
|
|
|
Leftover[0] -= SnapXY;
|
|
|
|
i++;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else if (Leftover[0] < -SnapXY / 2)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Leftover[0] += SnapXY;
|
|
|
|
i--;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Delta[0] = SnapXY * i;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_Y)
|
|
|
|
{
|
|
|
|
int i = (int)(Delta[1] / SnapXY);
|
|
|
|
Leftover[1] = Delta[1] - (SnapXY * i);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Leftover[1] > SnapXY / 2)
|
|
|
|
{
|
|
|
|
Leftover[1] -= SnapXY;
|
|
|
|
i++;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else if (Leftover[1] < -SnapXY / 2)
|
2014-05-01 16:55:12 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Leftover[1] += SnapXY;
|
|
|
|
i--;
|
|
|
|
}
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Delta[1] = SnapXY * i;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_SNAP_Z)
|
|
|
|
{
|
|
|
|
int i = (int)(Delta[2] / SnapZ);
|
|
|
|
Leftover[2] = Delta[2] - (SnapZ * i);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Leftover[2] > SnapZ / 2)
|
|
|
|
{
|
|
|
|
Leftover[2] -= SnapZ;
|
|
|
|
i++;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else if (Leftover[2] < -SnapZ / 2)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Leftover[2] += SnapZ;
|
|
|
|
i--;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Delta[2] = SnapZ * i;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::SnapRotationVector(lcVector3& Delta, lcVector3& Leftover) const
|
|
|
|
{
|
|
|
|
if (m_nSnap & LC_DRAW_SNAP_A)
|
|
|
|
{
|
|
|
|
int Snap[3];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
Snap[i] = (int)(Delta[i] / (float)m_nAngleSnap);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 NewDelta((float)(m_nAngleSnap * Snap[0]), (float)(m_nAngleSnap * Snap[1]), (float)(m_nAngleSnap * Snap[2]));
|
|
|
|
Leftover = Delta - NewDelta;
|
|
|
|
Delta = NewDelta;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcMatrix44 Project::GetRelativeRotation() const
|
|
|
|
{
|
|
|
|
if ((m_nSnap & LC_DRAW_GLOBAL_SNAP) == 0)
|
|
|
|
{
|
|
|
|
Object* Focus = GetFocusObject();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((Focus != NULL) && Focus->IsPiece())
|
|
|
|
{
|
|
|
|
lcMatrix44 WorldMatrix = ((Piece*)Focus)->mModelWorld;
|
|
|
|
WorldMatrix.SetTranslation(lcVector3(0.0f, 0.0f, 0.0f));
|
|
|
|
return WorldMatrix;
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return lcMatrix44Identity();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::MoveSelectedObjects(lcVector3& Move, lcVector3& Remainder, bool Snap, bool Lock)
|
|
|
|
{
|
|
|
|
// Don't move along locked directions.
|
|
|
|
if (Lock)
|
|
|
|
{
|
|
|
|
if (m_nSnap & LC_DRAW_LOCK_X)
|
|
|
|
Move[0] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Y)
|
|
|
|
Move[1] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Z)
|
|
|
|
Move[2] = 0;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Snap.
|
|
|
|
if (Snap)
|
|
|
|
{
|
|
|
|
SnapVector(Move, Remainder);
|
2014-05-01 16:55:12 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Move.LengthSquared() < 0.001f)
|
|
|
|
return false;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Transform the translation if we're in relative mode.
|
|
|
|
if ((m_nSnap & LC_DRAW_GLOBAL_SNAP) == 0)
|
|
|
|
{
|
|
|
|
Object* Focus = GetFocusObject();
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((Focus != NULL) && Focus->IsPiece())
|
|
|
|
Move = lcMul30(Move, ((Piece*)Focus)->mModelWorld);
|
|
|
|
}
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float x = Move[0], y = Move[1], z = Move[2];
|
2013-12-17 03:43:16 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* pCamera = mCameras[CameraIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pCamera->IsSelected())
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
pCamera->Move(m_nCurStep, gMainWindow->GetAddKeys(), x, y, z);
|
2014-05-18 01:03:05 +02:00
|
|
|
pCamera->UpdatePosition(m_nCurStep);
|
2014-05-01 16:55:12 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
{
|
|
|
|
Light* pLight = mLights[LightIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pLight->IsSelected())
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
pLight->Move (m_nCurStep, gMainWindow->GetAddKeys(), x, y, z);
|
2014-05-18 01:03:05 +02:00
|
|
|
pLight->UpdatePosition (m_nCurStep);
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Piece->Move(m_nCurStep, gMainWindow->GetAddKeys(), x, y, z);
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// TODO: move group centers
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return true;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Project::RotateSelectedObjects(lcVector3& Delta, lcVector3& Remainder, bool Snap, bool Lock)
|
|
|
|
{
|
|
|
|
// Don't move along locked directions.
|
|
|
|
if (Lock)
|
|
|
|
{
|
|
|
|
if (m_nSnap & LC_DRAW_LOCK_X)
|
|
|
|
Delta[0] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Y)
|
|
|
|
Delta[1] = 0;
|
|
|
|
|
|
|
|
if (m_nSnap & LC_DRAW_LOCK_Z)
|
|
|
|
Delta[2] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Snap.
|
|
|
|
if (Snap)
|
|
|
|
SnapRotationVector(Delta, Remainder);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Delta.LengthSquared() < 0.001f)
|
|
|
|
return false;
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
lcVector3 pos;
|
|
|
|
lcVector4 rot;
|
|
|
|
int nSel = 0;
|
|
|
|
Piece *pFocus = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
if (Piece->IsFocused())
|
|
|
|
pFocus = Piece;
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
nSel++;
|
|
|
|
}
|
|
|
|
}
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pFocus != NULL)
|
|
|
|
{
|
|
|
|
pos = pFocus->mPosition;
|
|
|
|
bs[0] = bs[3] = pos[0];
|
|
|
|
bs[1] = bs[4] = pos[1];
|
|
|
|
bs[2] = bs[5] = pos[2];
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Center((bs[0]+bs[3])/2, (bs[1]+bs[4])/2, (bs[2]+bs[5])/2);
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Create the rotation matrix.
|
|
|
|
lcVector4 RotationQuaternion(0, 0, 0, 1);
|
|
|
|
lcVector4 WorldToFocusQuaternion, FocusToWorldQuaternion;
|
2012-01-30 08:31:29 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!(m_nSnap & LC_DRAW_LOCK_X) && (Delta[0] != 0.0f))
|
|
|
|
{
|
|
|
|
lcVector4 q = lcQuaternionRotationX(Delta[0] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
|
|
|
}
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!(m_nSnap & LC_DRAW_LOCK_Y) && (Delta[1] != 0.0f))
|
|
|
|
{
|
|
|
|
lcVector4 q = lcQuaternionRotationY(Delta[1] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
|
|
|
}
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!(m_nSnap & LC_DRAW_LOCK_Z) && (Delta[2] != 0.0f))
|
2012-01-28 03:10:19 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 q = lcQuaternionRotationZ(Delta[2] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
2012-01-28 03:10:19 +01:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
// Transform the rotation relative to the focused piece.
|
|
|
|
if (m_nSnap & LC_DRAW_GLOBAL_SNAP)
|
|
|
|
pFocus = NULL;
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pFocus != NULL)
|
|
|
|
{
|
|
|
|
lcVector4 Rot;
|
|
|
|
Rot = ((Piece*)pFocus)->mRotation;
|
2011-09-20 03:26:31 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
WorldToFocusQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rot[0], Rot[1], Rot[2], -Rot[3] * LC_DTOR));
|
|
|
|
FocusToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(Rot[0], Rot[1], Rot[2], Rot[3] * LC_DTOR));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
RotationQuaternion = lcQuaternionMultiply(FocusToWorldQuaternion, RotationQuaternion);
|
|
|
|
}
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Piece->IsSelected())
|
|
|
|
continue;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pos = Piece->mPosition;
|
|
|
|
rot = Piece->mRotation;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 NewRotation;
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if ((nSel == 1) && (pFocus == Piece))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 LocalToWorldQuaternion;
|
|
|
|
LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], rot[3] * LC_DTOR));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 NewLocalToWorldQuaternion;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pFocus != NULL)
|
2014-04-09 00:34:50 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion);
|
|
|
|
NewLocalToWorldQuaternion = lcQuaternionMultiply(LocalToFocusQuaternion, RotationQuaternion);
|
2014-04-09 00:34:50 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
else
|
2012-08-22 03:13:32 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion);
|
2012-08-22 03:13:32 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion);
|
|
|
|
}
|
|
|
|
else
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Distance = lcVector3(pos[0], pos[1], pos[2]) - Center;
|
2012-01-28 03:10:19 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 LocalToWorldQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], rot[3] * LC_DTOR));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 NewLocalToWorldQuaternion;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pFocus != NULL)
|
|
|
|
{
|
|
|
|
lcVector4 LocalToFocusQuaternion = lcQuaternionMultiply(WorldToFocusQuaternion, LocalToWorldQuaternion);
|
|
|
|
NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToFocusQuaternion);
|
2013-08-09 06:57:18 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 WorldToLocalQuaternion = lcQuaternionFromAxisAngle(lcVector4(rot[0], rot[1], rot[2], -rot[3] * LC_DTOR));
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Distance = lcQuaternionMul(Distance, WorldToLocalQuaternion);
|
|
|
|
Distance = lcQuaternionMul(Distance, NewLocalToWorldQuaternion);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NewLocalToWorldQuaternion = lcQuaternionMultiply(RotationQuaternion, LocalToWorldQuaternion);
|
|
|
|
|
|
|
|
Distance = lcQuaternionMul(Distance, RotationQuaternion);
|
|
|
|
}
|
|
|
|
|
|
|
|
NewRotation = lcQuaternionToAxisAngle(NewLocalToWorldQuaternion);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
pos[0] = Center[0] + Distance[0];
|
|
|
|
pos[1] = Center[1] + Distance[1];
|
|
|
|
pos[2] = Center[2] + Distance[2];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-21 00:15:42 +02:00
|
|
|
Piece->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), pos, LC_PK_POSITION);
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
rot[0] = NewRotation[0];
|
|
|
|
rot[1] = NewRotation[1];
|
|
|
|
rot[2] = NewRotation[2];
|
|
|
|
rot[3] = NewRotation[3] * LC_RTOD;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-21 00:15:42 +02:00
|
|
|
Piece->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), rot, LC_PK_ROTATION);
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
}
|
2012-01-30 08:31:29 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
return true;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::TransformSelectedObjects(LC_TRANSFORM_TYPE Type, const lcVector3& Transform)
|
|
|
|
{
|
|
|
|
switch (Type)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TRANSFORM_ABSOLUTE_TRANSLATION:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float bs[6] = { 10000, 10000, 10000, -10000, -10000, -10000 };
|
|
|
|
lcVector3 Center;
|
|
|
|
int nSel = 0;
|
|
|
|
Piece* pFocus = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
2013-04-10 02:56:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
|
|
|
if (Piece->IsFocused())
|
|
|
|
pFocus = Piece;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->CompareBoundingBox(bs);
|
|
|
|
nSel++;
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pFocus != NULL)
|
|
|
|
Center = pFocus->mPosition;
|
|
|
|
else
|
|
|
|
Center = lcVector3((bs[0]+bs[3])/2, (bs[1]+bs[4])/2, (bs[2]+bs[5])/2);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Offset = Transform - Center;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
|
|
|
|
{
|
|
|
|
Camera* pCamera = mCameras[CameraIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pCamera->IsSelected())
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
pCamera->Move(m_nCurStep, gMainWindow->GetAddKeys(), Offset.x, Offset.y, Offset.z);
|
2014-05-18 01:03:05 +02:00
|
|
|
pCamera->UpdatePosition(m_nCurStep);
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
|
|
|
|
{
|
|
|
|
Light* pLight = mLights[LightIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (pLight->IsSelected())
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
pLight->Move(m_nCurStep, gMainWindow->GetAddKeys(), Offset.x, Offset.y, Offset.z);
|
2014-05-18 01:03:05 +02:00
|
|
|
pLight->UpdatePosition (m_nCurStep);
|
|
|
|
}
|
|
|
|
}
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Piece->Move(m_nCurStep, gMainWindow->GetAddKeys(), Offset.x, Offset.y, Offset.z);
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (nSel)
|
|
|
|
{
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Moving");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TRANSFORM_RELATIVE_TRANSLATION:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector3 Move(Transform), Remainder;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (MoveSelectedObjects(Move, Remainder, false, false))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Moving");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TRANSFORM_ABSOLUTE_ROTATION:
|
|
|
|
{
|
|
|
|
// Create the rotation matrix.
|
|
|
|
lcVector4 RotationQuaternion(0, 0, 0, 1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Transform[0] != 0.0f)
|
|
|
|
{
|
|
|
|
lcVector4 q = lcQuaternionRotationX(Transform[0] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Transform[1] != 0.0f)
|
|
|
|
{
|
|
|
|
lcVector4 q = lcQuaternionRotationY(Transform[1] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Transform[2] != 0.0f)
|
|
|
|
{
|
|
|
|
lcVector4 q = lcQuaternionRotationZ(Transform[2] * LC_DTOR);
|
|
|
|
RotationQuaternion = lcQuaternionMultiply(q, RotationQuaternion);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcVector4 NewRotation = lcQuaternionToAxisAngle(RotationQuaternion);
|
|
|
|
NewRotation[3] *= LC_RTOD;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
int nSel = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
|
|
|
{
|
|
|
|
Piece* Piece = mPieces[PieceIdx];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->IsSelected())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Piece->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), NewRotation, LC_PK_ROTATION);
|
2014-05-18 01:03:05 +02:00
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
nSel++;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (nSel)
|
|
|
|
{
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Rotating");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TRANSFORM_RELATIVE_ROTATION:
|
|
|
|
{
|
|
|
|
lcVector3 Rotate(Transform), Remainder;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (RotateSelectedObjects(Rotate, Remainder, false, false))
|
|
|
|
{
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Rotating");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ModifyObject(Object* Object, lcObjectProperty Property, void* Value)
|
|
|
|
{
|
|
|
|
const char* CheckPointString = NULL;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
switch (Property)
|
|
|
|
{
|
|
|
|
case LC_PIECE_PROPERTY_POSITION:
|
|
|
|
{
|
|
|
|
const lcVector3& Position = *(lcVector3*)Value;
|
|
|
|
Piece* Part = (Piece*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Part->mPosition != Position)
|
2014-05-21 00:15:42 +02:00
|
|
|
{
|
|
|
|
Part->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), Position, LC_PK_POSITION);
|
2014-05-18 01:03:05 +02:00
|
|
|
Part->UpdatePosition(m_nCurStep);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Moving";
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_PROPERTY_ROTATION:
|
|
|
|
{
|
|
|
|
const lcVector4& Rotation = *(lcVector4*)Value;
|
|
|
|
Piece* Part = (Piece*)Object;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Rotation != Part->mRotation)
|
2014-05-21 00:15:42 +02:00
|
|
|
{
|
|
|
|
Part->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), Rotation, LC_PK_ROTATION);
|
2014-05-18 01:03:05 +02:00
|
|
|
Part->UpdatePosition(m_nCurStep);
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Rotating";
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_PROPERTY_SHOW:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
lcuint32 Show = *(lcuint32*)Value;
|
|
|
|
Piece* Part = (Piece*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Show != Part->GetStepShow())
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
Part->SetStepShow(Show);
|
|
|
|
if (Part->IsSelected() && !Part->IsVisible(m_nCurStep))
|
|
|
|
Part->SetSelected(false);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Show";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_PROPERTY_HIDE:
|
|
|
|
{
|
|
|
|
lcuint32 Hide = *(lcuint32*)Value;
|
|
|
|
Piece* Part = (Piece*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Hide != Part->GetStepHide())
|
|
|
|
{
|
|
|
|
Part->SetStepHide(Hide);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Hide";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_PROPERTY_COLOR:
|
|
|
|
{
|
|
|
|
int ColorIndex = *(int*)Value;
|
|
|
|
Piece* Part = (Piece*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (ColorIndex != Part->mColorIndex)
|
|
|
|
{
|
|
|
|
Part->SetColorIndex(ColorIndex);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Color";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_PIECE_PROPERTY_ID:
|
|
|
|
{
|
|
|
|
Piece* Part = (Piece*)Object;
|
|
|
|
PieceInfo* Info = (PieceInfo*)Value;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Info != Part->mPieceInfo)
|
|
|
|
{
|
|
|
|
Part->mPieceInfo->Release();
|
|
|
|
Part->mPieceInfo = Info;
|
|
|
|
Part->mPieceInfo->AddRef();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Part";
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case LC_CAMERA_PROPERTY_POSITION:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
const lcVector3& Position = *(lcVector3*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->mPosition != Position)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
camera->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), Position, LC_CK_EYE);
|
2014-05-18 01:03:05 +02:00
|
|
|
camera->UpdatePosition(m_nCurStep);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_TARGET:
|
|
|
|
{
|
|
|
|
const lcVector3& TargetPosition = *(lcVector3*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->mTargetPosition != TargetPosition)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
camera->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), TargetPosition, LC_CK_TARGET);
|
2014-05-18 01:03:05 +02:00
|
|
|
camera->UpdatePosition(m_nCurStep);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_UPVECTOR:
|
|
|
|
{
|
|
|
|
const lcVector3& Up = *(lcVector3*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->mUpVector != Up)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
camera->ChangeKey(m_nCurStep, gMainWindow->GetAddKeys(), Up, LC_CK_UP);
|
2014-05-18 01:03:05 +02:00
|
|
|
camera->UpdatePosition(m_nCurStep);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_ORTHO:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
bool Ortho = *(bool*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->IsOrtho() != Ortho)
|
|
|
|
{
|
|
|
|
camera->SetOrtho(Ortho);
|
|
|
|
camera->UpdatePosition(m_nCurStep);
|
|
|
|
|
|
|
|
CheckPointString = "Camera";
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_FOV:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float FOV = *(float*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->m_fovy != FOV)
|
|
|
|
{
|
|
|
|
camera->m_fovy = FOV;
|
|
|
|
camera->UpdatePosition(m_nCurStep);
|
|
|
|
|
|
|
|
CheckPointString = "Camera";
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
} break;
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_NEAR:
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float Near = *(float*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->m_zNear != Near)
|
|
|
|
{
|
|
|
|
camera->m_zNear= Near;
|
|
|
|
camera->UpdatePosition(m_nCurStep);
|
2013-01-06 20:24:25 +01:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
|
|
|
}
|
|
|
|
} break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_FAR:
|
|
|
|
{
|
|
|
|
float Far = *(float*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (camera->m_zFar != Far)
|
2014-04-10 06:46:48 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
camera->m_zFar = Far;
|
|
|
|
camera->UpdatePosition(m_nCurStep);
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
2014-04-10 06:46:48 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
} break;
|
2014-04-10 06:46:48 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_CAMERA_PROPERTY_NAME:
|
|
|
|
{
|
|
|
|
const char* Name = (const char*)Value;
|
|
|
|
Camera* camera = (Camera*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (strcmp(camera->m_strName, Name))
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
strncpy(camera->m_strName, Name, sizeof(camera->m_strName));
|
|
|
|
camera->m_strName[sizeof(camera->m_strName) - 1] = 0;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
CheckPointString = "Camera";
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (CheckPointString)
|
|
|
|
{
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint(CheckPointString);
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ZoomActiveView(int Amount)
|
2013-01-28 20:57:33 +01:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
float ScaledAmount = 2.0f * Amount / (21 - lcGetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY));
|
|
|
|
|
2014-05-21 00:15:42 +02:00
|
|
|
gMainWindow->GetActiveView()->mCamera->Zoom(ScaledAmount, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
2013-01-28 20:57:33 +01:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BeginPieceDrop(PieceInfo* Info)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-18 01:03:05 +02:00
|
|
|
StartTracking(LC_TRACK_LEFT);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
mDropPiece = Info;
|
|
|
|
mDropPiece->AddRef();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::OnPieceDropMove(int x, int y)
|
|
|
|
{
|
|
|
|
if (!mDropPiece)
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (m_nDownX != x || m_nDownY != y)
|
|
|
|
{
|
|
|
|
m_nDownX = x;
|
|
|
|
m_nDownY = y;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::EndPieceDrop(bool Accept)
|
|
|
|
{
|
|
|
|
StopTracking(Accept);
|
2012-07-21 01:15:53 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (!Accept)
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BeginColorDrop()
|
|
|
|
{
|
|
|
|
StartTracking(LC_TRACK_LEFT);
|
2014-05-23 02:02:21 +02:00
|
|
|
gMainWindow->SetTool(LC_TOOL_PAINT);
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BeginMouseTool()
|
|
|
|
{
|
|
|
|
mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::EndMouseTool(lcTool Tool, bool Accept)
|
|
|
|
{
|
|
|
|
if (!Accept)
|
|
|
|
{
|
|
|
|
DeleteContents(true);
|
|
|
|
FileLoad(&m_pUndoList->file, true, false);
|
|
|
|
return;
|
|
|
|
}
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
switch (Tool)
|
|
|
|
{
|
|
|
|
case LC_TOOL_INSERT:
|
|
|
|
case LC_TOOL_LIGHT:
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_SPOTLIGHT:
|
|
|
|
CheckPoint("New SpotLight");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_CAMERA:
|
|
|
|
gMainWindow->UpdateCameraMenu();
|
|
|
|
CheckPoint("New Camera");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_SELECT:
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_MOVE:
|
|
|
|
CheckPoint("Move");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_ROTATE:
|
|
|
|
CheckPoint("Rotate");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_ERASER:
|
|
|
|
case LC_TOOL_PAINT:
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_ZOOM:
|
|
|
|
if (!gMainWindow->GetActiveView()->mCamera->IsSimple())
|
|
|
|
CheckPoint("Zoom");
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_PAN:
|
|
|
|
if (!gMainWindow->GetActiveView()->mCamera->IsSimple())
|
|
|
|
CheckPoint("Pan");
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_ROTATE_VIEW:
|
|
|
|
if (!gMainWindow->GetActiveView()->mCamera->IsSimple())
|
|
|
|
CheckPoint("Orbit");
|
|
|
|
break;
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_TOOL_ROLL:
|
|
|
|
if (!gMainWindow->GetActiveView()->mCamera->IsSimple())
|
|
|
|
CheckPoint("Roll");
|
|
|
|
break;
|
2014-05-21 00:15:42 +02:00
|
|
|
|
|
|
|
case LC_TOOL_ZOOM_REGION:
|
|
|
|
break;
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
|
|
|
}
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::InsertPieceToolClicked(const lcVector3& Position, const lcVector4& Rotation)
|
|
|
|
{
|
|
|
|
lcPiece* Piece = new lcPiece(m_pCurPiece);
|
|
|
|
Piece->Initialize(Position[0], Position[1], Position[2], m_nCurStep);
|
|
|
|
Piece->SetColorIndex(gMainWindow->mColorIndex);
|
|
|
|
Piece->ChangeKey(m_nCurStep, false, Rotation, LC_PK_ROTATION);
|
|
|
|
Piece->UpdatePosition(m_nCurStep);
|
|
|
|
Piece->CreateName(mPieces);
|
|
|
|
mPieces.Add(Piece);
|
|
|
|
|
|
|
|
SystemPieceComboAdd(m_pCurPiece->m_strDescription);
|
|
|
|
ClearSelectionAndSetFocus(Piece, LC_PIECE_SECTION_POSITION);
|
|
|
|
|
|
|
|
CheckPoint("Insert");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
}
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::PointLightToolClicked(const lcVector3& Position)
|
|
|
|
{
|
|
|
|
lcLight* Light = new lcLight(Position[0], Position[1], Position[2]);
|
|
|
|
Light->CreateName(mLights);
|
|
|
|
mLights.Add(Light);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION);
|
|
|
|
CheckPoint("New Light");
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target)
|
|
|
|
{
|
|
|
|
lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]);
|
|
|
|
mLights.Add(Light);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_TARGET);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateSpotLightTool(const lcVector3& Target)
|
|
|
|
{
|
|
|
|
lcLight* Light = mLights[mLights.GetSize() - 1];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Light->Move(1, false, Target[0], Target[1], Target[2]);
|
|
|
|
Light->UpdatePosition(1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(Light);
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::BeginCameraTool(const lcVector3& Position, const lcVector3& Target)
|
|
|
|
{
|
|
|
|
lcCamera* Camera = new lcCamera(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]);
|
|
|
|
Camera->CreateName(mCameras);
|
|
|
|
mCameras.Add(Camera);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateCameraTool(const lcVector3& Target)
|
|
|
|
{
|
|
|
|
lcCamera* Camera = mCameras[mCameras.GetSize() - 1];
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
Camera->Move(1, false, Target[0], Target[1], Target[2]);
|
|
|
|
Camera->UpdatePosition(1);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(Camera);
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateMoveTool(const lcVector3& Distance)
|
|
|
|
{
|
|
|
|
lcVector3 Delta, Remainder;
|
|
|
|
Delta = Distance - mMouseToolDistance;
|
|
|
|
MoveSelectedObjects(Delta, Remainder, true, true);
|
|
|
|
mMouseToolDistance += Delta;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateRotateTool(const lcVector3& Angles)
|
|
|
|
{
|
|
|
|
lcVector3 Delta, Remainder;
|
|
|
|
Delta = Angles - mMouseToolDistance;
|
|
|
|
RotateSelectedObjects(Delta, Remainder, true, true);
|
|
|
|
mMouseToolDistance += Delta;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::EraserToolClicked(lcObject* Object)
|
|
|
|
{
|
|
|
|
if (!Object)
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
switch (Object->GetType())
|
|
|
|
{
|
|
|
|
case LC_OBJECT_PIECE:
|
|
|
|
mPieces.Remove((Piece*)Object);
|
|
|
|
RemoveEmptyGroups();
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_OBJECT_CAMERA:
|
|
|
|
{
|
|
|
|
const lcArray<View*> Views = gMainWindow->GetViews();
|
|
|
|
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
|
|
|
|
{
|
|
|
|
View* View = Views[ViewIdx];
|
|
|
|
Camera* Camera = View->mCamera;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Camera == Object)
|
|
|
|
View->SetCamera(Camera, true);
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
mCameras.Remove((Camera*)Object);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateCameraMenu();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
case LC_OBJECT_LIGHT:
|
|
|
|
mLights.Remove((Light*)Object);
|
|
|
|
break;
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
delete Object;
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
UpdateSelection();
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Deleting");
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::PaintToolClicked(lcObject* Object)
|
|
|
|
{
|
|
|
|
if (!Object || Object->GetType() != LC_OBJECT_PIECE)
|
|
|
|
return;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
lcPiece* Piece = (lcPiece*)Object;
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
if (Piece->mColorIndex != gMainWindow->mColorIndex)
|
|
|
|
{
|
|
|
|
Piece->SetColorIndex(gMainWindow->mColorIndex);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
SetModifiedFlag(true);
|
|
|
|
CheckPoint("Painting");
|
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2014-05-18 01:03:05 +02:00
|
|
|
}
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateZoomTool(lcCamera* Camera, float Mouse)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Camera->Zoom(Mouse - mMouseToolDistance.x, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
mMouseToolDistance.x = Mouse;
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdatePanTool(lcCamera* Camera, float MouseX, float MouseY)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Camera->Pan(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
mMouseToolDistance.x = MouseX;
|
|
|
|
mMouseToolDistance.y = MouseY;
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY)
|
|
|
|
{
|
|
|
|
lcVector3 Center;
|
|
|
|
GetSelectionCenter(Center);
|
2014-05-21 00:15:42 +02:00
|
|
|
Camera->Orbit(MouseX - mMouseToolDistance.x, MouseY - mMouseToolDistance.y, Center, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
mMouseToolDistance.x = MouseX;
|
|
|
|
mMouseToolDistance.y = MouseY;
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
}
|
2012-07-31 07:27:40 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::UpdateRollTool(lcCamera* Camera, float Mouse)
|
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Camera->Roll(Mouse - mMouseToolDistance.x, m_nCurStep, gMainWindow->GetAddKeys());
|
2014-05-18 01:03:05 +02:00
|
|
|
mMouseToolDistance.x = Mouse;
|
|
|
|
gMainWindow->UpdateAllViews();
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
void Project::ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY)
|
2011-09-07 23:06:51 +02:00
|
|
|
{
|
2014-05-21 00:15:42 +02:00
|
|
|
Camera->ZoomRegion(Points, m_nCurStep, gMainWindow->GetAddKeys(), RatioX, RatioY);
|
2011-09-07 23:06:51 +02:00
|
|
|
|
2014-05-18 01:03:05 +02:00
|
|
|
gMainWindow->UpdateFocusObject(GetFocusObject());
|
|
|
|
gMainWindow->UpdateAllViews();
|
|
|
|
|
|
|
|
if (!Camera->IsSimple())
|
|
|
|
CheckPoint("Zoom");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::OnMouseWheel(View* view, float Direction)
|
|
|
|
{
|
|
|
|
ZoomActiveView((int)((view->mInputState.Control ? 100 : 10) * Direction));
|
2011-09-07 23:06:51 +02:00
|
|
|
}
|
2013-12-19 14:41:49 +01:00
|
|
|
|
|
|
|
// Indicates if the existing string represents an instance of the candidate
|
|
|
|
// string in the form "<basename> (#<instance>)".
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
// -1 if existing is not an instance of candidate.
|
|
|
|
// 0 if existing is an instance but not numbered.
|
|
|
|
// >= 1 indicates the existing instance number.
|
|
|
|
//
|
2014-01-26 00:38:03 +01:00
|
|
|
int Project::InstanceOfName(const String& existingString, const String& candidateString, String& baseNameOut)
|
2013-12-19 14:41:49 +01:00
|
|
|
{
|
|
|
|
int einst = 0;
|
|
|
|
String estr = existingString;
|
|
|
|
estr.TrimLeft();
|
|
|
|
estr.TrimRight();
|
|
|
|
|
|
|
|
int div = estr.ReverseFind('#');
|
|
|
|
if (-1 != div)
|
|
|
|
{
|
|
|
|
char* endptr;
|
|
|
|
einst = strtol(estr.Mid(div + 1), &endptr, 10);
|
|
|
|
if (!*endptr)
|
|
|
|
{
|
|
|
|
estr = estr.Left(div);
|
|
|
|
estr.TrimRight();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String cstr = candidateString;
|
|
|
|
cstr.TrimLeft();
|
|
|
|
cstr.TrimRight();
|
|
|
|
|
|
|
|
div = cstr.ReverseFind('#');
|
|
|
|
if (-1 != div)
|
|
|
|
{
|
|
|
|
char* endptr;
|
2014-01-26 00:38:03 +01:00
|
|
|
int Value = strtol(cstr.Mid(div + 1), &endptr, 10);
|
|
|
|
(void)Value;
|
2013-12-19 14:41:49 +01:00
|
|
|
if (!*endptr)
|
|
|
|
{
|
|
|
|
cstr = cstr.Left(div);
|
|
|
|
cstr.TrimRight();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (estr.CompareNoCase(cstr))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
baseNameOut = estr;
|
|
|
|
return einst;
|
|
|
|
}
|