pax_global_header00006660000000000000000000000064124657623120014522gustar00rootroot0000000000000052 comment=e86e36c6086604421a8e56428d3d19c2dbfa8149 leocad-0.81+svn1775/000077500000000000000000000000001246576231200140275ustar00rootroot00000000000000leocad-0.81+svn1775/common/000077500000000000000000000000001246576231200153175ustar00rootroot00000000000000leocad-0.81+svn1775/common/camera.cpp000066400000000000000000000664641246576231200172730ustar00rootroot00000000000000#include "lc_global.h" #include "lc_math.h" #include "lc_colors.h" #include #include #include #include #include "opengl.h" #include "lc_file.h" #include "camera.h" #include "view.h" #include "tr.h" #include "lc_application.h" #include "lc_context.h" #define LC_CAMERA_POSITION_EDGE 7.5f #define LC_CAMERA_TARGET_EDGE 7.5f #define LC_CAMERA_SAVE_VERSION 7 // LeoCAD 0.80 lcCamera::lcCamera(bool Simple) : lcObject(LC_OBJECT_CAMERA) { Initialize(); if (Simple) mState |= LC_CAMERA_SIMPLE; else { mPosition = lcVector3(-250.0f, -250.0f, 75.0f); mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f); mOrthoTarget = mTargetPosition; mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); ChangeKey(mPositionKeys, mPosition, 1, true); ChangeKey(mTargetPositionKeys, mTargetPosition, 1, true); ChangeKey(mUpVectorKeys, mUpVector, 1, true); UpdatePosition(1); } } lcCamera::lcCamera(float ex, float ey, float ez, float tx, float ty, float tz) : lcObject(LC_OBJECT_CAMERA) { // Fix the up vector lcVector3 UpVector(0, 0, 1), FrontVector(ex - tx, ey - ty, ez - tz), SideVector; FrontVector.Normalize(); if (FrontVector == UpVector) SideVector = lcVector3(1, 0, 0); else SideVector = lcCross(FrontVector, UpVector); UpVector = lcCross(SideVector, FrontVector); UpVector.Normalize(); Initialize(); ChangeKey(mPositionKeys, lcVector3(ex, ey, ez), 1, true); ChangeKey(mTargetPositionKeys, lcVector3(tx, ty, tz), 1, true); ChangeKey(mUpVectorKeys, UpVector, 1, true); UpdatePosition(1); } lcCamera::~lcCamera() { } void lcCamera::Initialize() { m_fovy = 30.0f; m_zNear = 25.0f; m_zFar = 12500.0f; mState = 0; m_pTR = NULL; memset(m_strName, 0, sizeof(m_strName)); } void lcCamera::CreateName(const lcArray& Cameras) { if (m_strName[0]) { bool Found = false; for (int CameraIdx = 0; CameraIdx < Cameras.GetSize(); CameraIdx++) { if (!strcmp(Cameras[CameraIdx]->m_strName, m_strName)) { Found = true; break; } } if (!Found) return; } int i, max = 0; const char* Prefix = "Camera "; for (int CameraIdx = 0; CameraIdx < Cameras.GetSize(); CameraIdx++) if (strncmp(Cameras[CameraIdx]->m_strName, Prefix, strlen(Prefix)) == 0) if (sscanf(Cameras[CameraIdx]->m_strName + strlen(Prefix), " %d", &i) == 1) if (i > max) max = i; sprintf(m_strName, "%s %d", Prefix, max+1); } void lcCamera::SaveLDraw(QTextStream& Stream) const { QLatin1String LineEnding("\r\n"); Stream << QLatin1String("0 !LEOCAD CAMERA FOV ") << m_fovy << QLatin1String(" ZNEAR ") << m_zNear << QLatin1String(" ZFAR ") << m_zFar << LineEnding; if (mPositionKeys.GetSize() > 1) SaveKeysLDraw(Stream, mPositionKeys, "CAMERA POSITION_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA POSITION ") << mPosition[0] << ' ' << mPosition[1] << ' ' << mPosition[2] << LineEnding; if (mTargetPositionKeys.GetSize() > 1) SaveKeysLDraw(Stream, mTargetPositionKeys, "CAMERA TARGET_POSITION_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA TARGET_POSITION ") << mTargetPosition[0] << ' ' << mTargetPosition[1] << ' ' << mTargetPosition[2] << LineEnding; if (mUpVectorKeys.GetSize() > 1) SaveKeysLDraw(Stream, mUpVectorKeys, "CAMERA UP_VECTOR_KEY "); else Stream << QLatin1String("0 !LEOCAD CAMERA UP_VECTOR ") << mUpVector[0] << ' ' << mUpVector[1] << ' ' << mUpVector[2] << LineEnding; Stream << QLatin1String("0 !LEOCAD CAMERA "); if (IsHidden()) Stream << QLatin1String("HIDDEN"); if (IsOrtho()) Stream << QLatin1String("ORTHOGRAPHIC "); Stream << QLatin1String("NAME ") << m_strName << LineEnding; } bool lcCamera::ParseLDrawLine(QTextStream& Stream) { while (!Stream.atEnd()) { QString Token; Stream >> Token; if (Token == QLatin1String("HIDDEN")) SetHidden(true); else if (Token == QLatin1String("ORTHOGRAPHIC")) SetOrtho(true); else if (Token == QLatin1String("FOV")) Stream >> m_fovy; else if (Token == QLatin1String("ZNEAR")) Stream >> m_zNear; else if (Token == QLatin1String("ZFAR")) Stream >> m_zFar; else if (Token == QLatin1String("POSITION")) Stream >> mPosition[0] >> mPosition[1] >> mPosition[2]; else if (Token == QLatin1String("TARGET_POSITION")) Stream >> mTargetPosition[0] >> mTargetPosition[1] >> mTargetPosition[2]; else if (Token == QLatin1String("UP_VECTOR")) Stream >> mUpVector[0] >> mUpVector[1] >> mUpVector[2]; else if (Token == QLatin1String("POSITION_KEY")) LoadKeysLDraw(Stream, mPositionKeys); else if (Token == QLatin1String("TARGET_POSITION_KEY")) LoadKeysLDraw(Stream, mTargetPositionKeys); else if (Token == QLatin1String("UP_VECTOR_KEY")) LoadKeysLDraw(Stream, mUpVectorKeys); else if (Token == QLatin1String("NAME")) { QString Name = Stream.readAll().trimmed(); QByteArray NameUtf = Name.toUtf8(); // todo: replace with qstring strncpy(m_strName, NameUtf.constData(), sizeof(m_strName)); m_strName[sizeof(m_strName) - 1] = 0; return true; } } return false; } ///////////////////////////////////////////////////////////////////////////// // Camera save/load bool lcCamera::FileLoad(lcFile& file) { lcuint8 version, ch; version = file.ReadU8(); if (version > LC_CAMERA_SAVE_VERSION) return false; if (version > 5) { if (file.ReadU8() != 1) return false; lcuint16 time; float param[4]; lcuint8 type; lcuint32 n; file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); if (type == 0) ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); else if (type == 1) ChangeKey(mTargetPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); else if (type == 2) ChangeKey(mUpVectorKeys, lcVector3(param[0], param[1], param[2]), time, true); } file.ReadU32(&n, 1); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 4); file.ReadU8(&type, 1); } } if (version == 4) { file.ReadBuffer(m_strName, 80); m_strName[80] = 0; } else { ch = file.ReadU8(); if (ch == 0xFF) return false; // don't read CString file.ReadBuffer(m_strName, ch); m_strName[ch] = 0; } if (version < 3) { double d[3]; float f[3]; file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; ChangeKey(mPositionKeys, lcVector3(f[0], f[1], f[2]), 1, true); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; ChangeKey(mTargetPositionKeys, lcVector3(f[0], f[1], f[2]), 1, true); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; ChangeKey(mUpVectorKeys, lcVector3(f[0], f[1], f[2]), 1, true); } if (version == 3) { ch = file.ReadU8(); while (ch--) { lcuint8 step; double eye[3], target[3], up[3]; float f[3]; file.ReadDoubles(eye, 3); file.ReadDoubles(target, 3); file.ReadDoubles(up, 3); file.ReadU8(&step, 1); if (up[0] == 0 && up[1] == 0 && up[2] == 0) up[2] = 1; f[0] = (float)eye[0]; f[1] = (float)eye[1]; f[2] = (float)eye[2]; ChangeKey(mPositionKeys, lcVector3(f[0], f[1], f[2]), step, true); f[0] = (float)target[0]; f[1] = (float)target[1]; f[2] = (float)target[2]; ChangeKey(mTargetPositionKeys, lcVector3(f[0], f[1], f[2]), step, true); f[0] = (float)up[0]; f[1] = (float)up[1]; f[2] = (float)up[2]; ChangeKey(mUpVectorKeys, lcVector3(f[0], f[1], f[2]), step, true); file.ReadS32(); // snapshot file.ReadS32(); // cam } } if (version < 4) { m_fovy = (float)file.ReadDouble(); m_zFar = (float)file.ReadDouble(); m_zNear= (float)file.ReadDouble(); } else { lcint32 n; if (version < 6) { lcuint16 time; float param[4]; lcuint8 type; n = file.ReadS32(); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 3); file.ReadU8(&type, 1); if (type == 0) ChangeKey(mPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); else if (type == 1) ChangeKey(mTargetPositionKeys, lcVector3(param[0], param[1], param[2]), time, true); else if (type == 2) ChangeKey(mUpVectorKeys, lcVector3(param[0], param[1], param[2]), time, true); } n = file.ReadS32(); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 3); file.ReadU8(&type, 1); } } file.ReadFloats(&m_fovy, 1); file.ReadFloats(&m_zFar, 1); file.ReadFloats(&m_zNear, 1); if (version < 5) { n = file.ReadS32(); if (n != 0) mState |= LC_CAMERA_HIDDEN; } else { ch = file.ReadU8(); if (ch & 1) mState |= LC_CAMERA_HIDDEN; file.ReadU8(); } } if ((version > 1) && (version < 4)) { lcuint32 show; lcint32 user; file.ReadU32(&show, 1); // if (version > 2) file.ReadS32(&user, 1); if (show == 0) mState |= LC_CAMERA_HIDDEN; } if (version < 7) { m_zFar *= 25.0f; m_zNear *= 25.0f; for (int KeyIdx = 0; KeyIdx < mPositionKeys.GetSize(); KeyIdx++) mPositionKeys[KeyIdx].Value *= 25.0f; for (int KeyIdx = 0; KeyIdx < mTargetPositionKeys.GetSize(); KeyIdx++) mTargetPositionKeys[KeyIdx].Value *= 25.0f; } return true; } void lcCamera::CompareBoundingBox(float box[6]) { const lcVector3 Points[2] = { mPosition, mTargetPosition }; for (int i = 0; i < 2; i++) { const lcVector3& Point = Points[i]; if (Point[0] < box[0]) box[0] = Point[0]; if (Point[1] < box[1]) box[1] = Point[1]; if (Point[2] < box[2]) box[2] = Point[2]; if (Point[0] > box[3]) box[3] = Point[0]; if (Point[1] > box[4]) box[4] = Point[1]; if (Point[2] > box[5]) box[5] = Point[2]; } } void lcCamera::Move(lcStep Step, bool AddKey, const lcVector3& Distance) { if (IsSimple()) AddKey = false; if (IsSelected(LC_CAMERA_SECTION_POSITION)) { mPosition += Distance; lcAlign(mOrthoTarget, mPosition, mTargetPosition); ChangeKey(mPositionKeys, mPosition, Step, AddKey); } if (IsSelected(LC_CAMERA_SECTION_TARGET)) { mTargetPosition += Distance; ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); } else if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) { mUpVector += Distance; mUpVector.Normalize(); ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); } lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); if (fabsf(lcDot(mUpVector, SideVector)) > 0.99f) SideVector = lcVector3(1, 0, 0); mUpVector = lcCross(SideVector, FrontVector); mUpVector.Normalize(); } void lcCamera::UpdatePosition(lcStep Step) { if (!IsSimple()) { mPosition = CalculateKey(mPositionKeys, Step); mTargetPosition = CalculateKey(mTargetPositionKeys, Step); mUpVector = CalculateKey(mUpVectorKeys, Step); } lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); mWorldView = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector); } void lcCamera::CopyPosition(const lcCamera* camera) { m_fovy = camera->m_fovy; m_zNear = camera->m_zNear; m_zFar = camera->m_zFar; mWorldView = camera->mWorldView; mPosition = camera->mPosition; mTargetPosition = camera->mTargetPosition; mOrthoTarget = camera->mOrthoTarget; mUpVector = camera->mUpVector; } void lcCamera::DrawInterface(lcContext* Context, const lcMatrix44& ViewMatrix) const { float LineWidth = lcGetPreferences().mLineWidth; lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld); float PositionEdge = LC_CAMERA_POSITION_EDGE; float PositionLens = LC_CAMERA_POSITION_EDGE * 2; float TargetEdge = LC_CAMERA_TARGET_EDGE; float Verts[34 + 24 + 4][3] = { { PositionEdge, PositionEdge, PositionEdge }, { -PositionEdge, PositionEdge, PositionEdge }, { -PositionEdge, PositionEdge, PositionEdge }, { -PositionEdge, -PositionEdge, PositionEdge }, { -PositionEdge, -PositionEdge, PositionEdge }, { PositionEdge, -PositionEdge, PositionEdge }, { PositionEdge, -PositionEdge, PositionEdge }, { PositionEdge, PositionEdge, PositionEdge }, { PositionEdge, PositionEdge, -PositionEdge }, { -PositionEdge, PositionEdge, -PositionEdge }, { -PositionEdge, PositionEdge, -PositionEdge }, { -PositionEdge, -PositionEdge, -PositionEdge }, { -PositionEdge, -PositionEdge, -PositionEdge }, { PositionEdge, -PositionEdge, -PositionEdge }, { PositionEdge, -PositionEdge, -PositionEdge }, { PositionEdge, PositionEdge, -PositionEdge }, { PositionEdge, PositionEdge, PositionEdge }, { PositionEdge, PositionEdge, -PositionEdge }, { -PositionEdge, PositionEdge, PositionEdge }, { -PositionEdge, PositionEdge, -PositionEdge }, { -PositionEdge, -PositionEdge, PositionEdge }, { -PositionEdge, -PositionEdge, -PositionEdge }, { PositionEdge, -PositionEdge, PositionEdge }, { PositionEdge, -PositionEdge, -PositionEdge }, { -PositionEdge, -PositionEdge, -PositionLens }, { -PositionEdge, PositionEdge, -PositionLens }, { 0.0f, 0.0f, -PositionEdge }, { -PositionEdge, -PositionEdge, -PositionLens }, { PositionEdge, -PositionEdge, -PositionLens }, { 0.0f, 0.0f, -PositionEdge }, { PositionEdge, PositionEdge, -PositionLens }, { PositionEdge, -PositionEdge, -PositionLens }, { PositionEdge, PositionEdge, -PositionLens }, { -PositionEdge, PositionEdge, -PositionLens }, { TargetEdge, TargetEdge, TargetEdge }, { -TargetEdge, TargetEdge, TargetEdge }, { -TargetEdge, TargetEdge, TargetEdge }, { -TargetEdge, -TargetEdge, TargetEdge }, { -TargetEdge, -TargetEdge, TargetEdge }, { TargetEdge, -TargetEdge, TargetEdge }, { TargetEdge, -TargetEdge, TargetEdge }, { TargetEdge, TargetEdge, TargetEdge }, { TargetEdge, TargetEdge, -TargetEdge }, { -TargetEdge, TargetEdge, -TargetEdge }, { -TargetEdge, TargetEdge, -TargetEdge }, { -TargetEdge, -TargetEdge, -TargetEdge }, { -TargetEdge, -TargetEdge, -TargetEdge }, { TargetEdge, -TargetEdge, -TargetEdge }, { TargetEdge, -TargetEdge, -TargetEdge }, { TargetEdge, TargetEdge, -TargetEdge }, { TargetEdge, TargetEdge, TargetEdge }, { TargetEdge, TargetEdge, -TargetEdge }, { -TargetEdge, TargetEdge, TargetEdge }, { -TargetEdge, TargetEdge, -TargetEdge }, { -TargetEdge, -TargetEdge, TargetEdge }, { -TargetEdge, -TargetEdge, -TargetEdge }, { TargetEdge, -TargetEdge, TargetEdge }, { TargetEdge, -TargetEdge, -TargetEdge }, { mPosition[0], mPosition[1], mPosition[2] }, { mTargetPosition[0], mTargetPosition[1], mTargetPosition[2] }, { mPosition[0], mPosition[1], mPosition[2] }, { UpVectorPosition[0], UpVectorPosition[1], UpVectorPosition[2] }, }; Context->SetWorldViewMatrix(lcMul(ViewWorld, ViewMatrix)); if (IsSelected(LC_CAMERA_SECTION_POSITION)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_POSITION)) lcSetColorFocused(); else lcSetColorSelected(); } else { Context->SetLineWidth(LineWidth); lcSetColorCamera(); } glVertexPointer(3, GL_FLOAT, 0, Verts); glDrawArrays(GL_LINES, 0, 24); glDrawArrays(GL_LINE_STRIP, 24, 10); lcMatrix44 TargetMat = ViewWorld; TargetMat.SetTranslation(mTargetPosition); Context->SetWorldViewMatrix(lcMul(TargetMat, ViewMatrix)); if (IsSelected(LC_CAMERA_SECTION_TARGET)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_TARGET)) lcSetColorFocused(); else lcSetColorSelected(); } else { Context->SetLineWidth(LineWidth); lcSetColorCamera(); } glDrawArrays(GL_LINES, 34, 24); lcMatrix44 UpVectorMat = ViewWorld; UpVectorMat.SetTranslation(UpVectorPosition); Context->SetWorldViewMatrix(lcMul(UpVectorMat, ViewMatrix)); if (IsSelected(LC_CAMERA_SECTION_UPVECTOR)) { Context->SetLineWidth(2.0f * LineWidth); if (IsFocused(LC_CAMERA_SECTION_UPVECTOR)) lcSetColorFocused(); else lcSetColorSelected(); } else { Context->SetLineWidth(LineWidth); lcSetColorCamera(); } glDrawArrays(GL_LINES, 34, 24); Context->SetWorldViewMatrix(ViewMatrix); lcSetColorCamera(); Context->SetLineWidth(LineWidth); glDrawArrays(GL_LINES, 34 + 24, 4); if (IsSelected()) { Context->SetWorldViewMatrix(lcMul(ViewWorld, ViewMatrix)); float Dist = lcLength(mTargetPosition - mPosition); lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, 1.33f, 0.01f, Dist); Projection = lcMatrix44Inverse(Projection); glMultMatrixf(Projection); float ProjVerts[16][3] = { { 1, 1, 1 }, { -1, 1, 1 }, { -1, 1, 1 }, { -1, -1, 1 }, { -1, -1, 1 }, { 1, -1, 1 }, { 1, -1, 1 }, { 1, 1, 1 }, { 1, 1, -1 }, { 1, 1, 1 }, { -1, 1, -1 }, { -1, 1, 1 }, { -1, -1, -1 }, { -1, -1, 1 }, { 1, -1, -1 }, { 1, -1, 1 }, }; glVertexPointer(3, GL_FLOAT, 0, ProjVerts); glDrawArrays(GL_LINES, 0, 16); } } void lcCamera::RayTest(lcObjectRayTest& ObjectRayTest) const { lcVector3 Min = lcVector3(-LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE); lcVector3 Max = lcVector3(LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE); lcVector3 Start = lcMul31(ObjectRayTest.Start, mWorldView); lcVector3 End = lcMul31(ObjectRayTest.End, mWorldView); float Distance; if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_POSITION; ObjectRayTest.Distance = Distance; } Min = lcVector3(-LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE); Max = lcVector3(LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE); lcMatrix44 WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView)); Start = lcMul31(ObjectRayTest.Start, WorldView); End = lcMul31(ObjectRayTest.End, WorldView); if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_TARGET; ObjectRayTest.Distance = Distance; } lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld); WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView)); Start = lcMul31(ObjectRayTest.Start, WorldView); End = lcMul31(ObjectRayTest.End, WorldView); if (lcBoundingBoxRayIntersectDistance(Min, Max, Start, End, &Distance, NULL) && (Distance < ObjectRayTest.Distance)) { ObjectRayTest.ObjectSection.Object = const_cast(this); ObjectRayTest.ObjectSection.Section = LC_CAMERA_SECTION_UPVECTOR; ObjectRayTest.Distance = Distance; } } void lcCamera::BoxTest(lcObjectBoxTest& ObjectBoxTest) const { lcVector3 Min(-LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE, -LC_CAMERA_POSITION_EDGE); lcVector3 Max(LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE, LC_CAMERA_POSITION_EDGE); lcVector4 LocalPlanes[6]; for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], mWorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(mWorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } Min = lcVector3(-LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE, -LC_CAMERA_TARGET_EDGE); Max = lcVector3(LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE, LC_CAMERA_TARGET_EDGE); lcMatrix44 WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-mTargetPosition, WorldView)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); lcVector3 UpVectorPosition = lcMul31(lcVector3(0, 1, 0), ViewWorld); WorldView = mWorldView; WorldView.SetTranslation(lcMul30(-UpVectorPosition, WorldView)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { lcVector3 Normal = lcMul30(ObjectBoxTest.Planes[PlaneIdx], WorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, ObjectBoxTest.Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal)); } if (lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes)) { ObjectBoxTest.Objects.Add(const_cast(this)); return; } } void lcCamera::InsertTime(lcStep Start, lcStep Time) { lcObject::InsertTime(mPositionKeys, Start, Time); lcObject::InsertTime(mTargetPositionKeys, Start, Time); lcObject::InsertTime(mUpVectorKeys, Start, Time); } void lcCamera::RemoveTime(lcStep Start, lcStep Time) { lcObject::RemoveTime(mPositionKeys, Start, Time); lcObject::RemoveTime(mTargetPositionKeys, Start, Time); lcObject::RemoveTime(mUpVectorKeys, Start, Time); } void lcCamera::ZoomExtents(float Aspect, const lcVector3& Center, const lcVector3* Points, int NumPoints, lcStep Step, bool AddKey) { lcVector3 Position(mPosition + Center - mTargetPosition); lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar); mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints); mTargetPosition = Center; mOrthoTarget = mTargetPosition; if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, lcStep Step, bool AddKey) { // Center camera. lcVector3 Eye = mPosition; Eye = Eye + (Points[0] - Points[1]); lcVector3 Target = mTargetPosition; Target = Target + (Points[0] - Points[1]); // Zoom in/out. float ZoomFactor = -lcMax(RatioX, RatioY) + 0.75f; lcVector3 Dir = Points[1] - Points[2]; mPosition = Eye + Dir * ZoomFactor; mTargetPosition = Target + Dir * ZoomFactor; // Change the camera and redraw. if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Zoom(float Distance, lcStep Step, bool AddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); FrontVector.Normalize(); FrontVector *= -5.0f * Distance; // Don't zoom ortho in if it would cross the ortho focal plane. if (IsOrtho()) { if ((Distance > 0) && (lcDot(mPosition + FrontVector - mOrthoTarget, mPosition - mOrthoTarget) <= 0)) return; } mPosition += FrontVector; mTargetPosition += FrontVector; if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Pan(const lcVector3& Distance, lcStep Step, bool AddKey) { mPosition += Distance; mTargetPosition += Distance; mOrthoTarget += Distance; if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 Z(lcNormalize(lcVector3(FrontVector[0], FrontVector[1], 0))); if (isnan(Z[0]) || isnan(Z[1])) Z = lcNormalize(lcVector3(mUpVector[0], mUpVector[1], 0)); if (mUpVector[2] < 0) { Z[0] = -Z[0]; Z[1] = -Z[1]; } lcMatrix44 YRot(lcVector4(Z[0], Z[1], 0.0f, 0.0f), lcVector4(-Z[1], Z[0], 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f)); lcMatrix44 transform = lcMul(lcMul(lcMul(lcMatrix44AffineInverse(YRot), lcMatrix44RotationY(DistanceY)), YRot), lcMatrix44RotationZ(-DistanceX)); mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition; mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; lcAlign(mOrthoTarget, mPosition, mTargetPosition); mUpVector = lcMul31(mUpVector, transform); if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } void lcCamera::Roll(float Distance, lcStep Step, bool AddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, Distance); mUpVector = lcMul30(mUpVector, Rotation); if (IsSimple()) AddKey = false; ChangeKey(mUpVectorKeys, mUpVector, Step, AddKey); UpdatePosition(Step); } void lcCamera::Center(lcVector3& point, lcStep Step, bool AddKey) { lcAlign(mTargetPosition, mPosition, point); if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } void lcCamera::SetViewpoint(lcViewpoint Viewpoint) { lcVector3 Positions[] = { lcVector3( 0.0f, -1250.0f, 0.0f), // LC_VIEWPOINT_FRONT lcVector3( 0.0f, 1250.0f, 0.0f), // LC_VIEWPOINT_BACK lcVector3( 0.0f, 0.0f, 1250.0f), // LC_VIEWPOINT_TOP lcVector3( 0.0f, 0.0f, -1250.0f), // LC_VIEWPOINT_BOTTOM lcVector3( 1250.0f, 0.0f, 0.0f), // LC_VIEWPOINT_LEFT lcVector3(-1250.0f, 0.0f, 0.0f), // LC_VIEWPOINT_RIGHT lcVector3( -375.0f, -375.0f, 187.5f) // LC_VIEWPOINT_HOME }; lcVector3 Ups[] = { lcVector3( 0.0f, 0.0f, 1.0f), lcVector3( 0.0f, 0.0f, 1.0f), lcVector3( 0.0f, 1.0f, 0.0f), lcVector3( 0.0f,-1.0f, 0.0f), lcVector3( 0.0f, 0.0f, 1.0f), lcVector3( 0.0f, 0.0f, 1.0f), lcVector3(-0.2357f, -0.2357f, 0.94281f) }; mPosition = Positions[Viewpoint]; mTargetPosition = lcVector3(0, 0, 0); mOrthoTarget = mTargetPosition; mUpVector = Ups[Viewpoint]; ChangeKey(mPositionKeys, mPosition, 1, false); ChangeKey(mTargetPositionKeys, mTargetPosition, 1, false); ChangeKey(mUpVectorKeys, mUpVector, 1, false); UpdatePosition(1); } void lcCamera::StartTiledRendering(int tw, int th, int iw, int ih, float AspectRatio) { m_pTR = new TiledRender(); m_pTR->TileSize(tw, th, 0); m_pTR->ImageSize(iw, ih); if (IsOrtho()) { float f = (mPosition - mOrthoTarget).Length(); float d = (m_fovy * f) * (LC_PI / 180.0f); float r = d / 2; float right = r * AspectRatio; m_pTR->Ortho(-right, right, -r, r, m_zNear, m_zFar * 4); } else m_pTR->Perspective(m_fovy, AspectRatio, m_zNear, m_zFar); } void lcCamera::GetTileInfo(int* row, int* col, int* width, int* height) { if (m_pTR != NULL) { *row = m_pTR->m_Rows - m_pTR->m_CurrentRow - 1; *col = m_pTR->m_CurrentColumn; *width = m_pTR->m_CurrentTileWidth; *height = m_pTR->m_CurrentTileHeight; } } bool lcCamera::EndTile() { if (m_pTR != NULL) { if (m_pTR->EndTile()) return true; delete m_pTR; m_pTR = NULL; } return false; } void lcCamera::SetFocalPoint(const lcVector3& focus, lcStep Step, bool AddKey) { if (IsOrtho()) { lcVector3 FocusVector = focus; lcAlign(FocusVector, mPosition, mTargetPosition); lcAlign(mOrthoTarget, mPosition, mTargetPosition); lcVector3 TranslateVector = FocusVector - mOrthoTarget; mPosition += TranslateVector; mTargetPosition += TranslateVector; mOrthoTarget = FocusVector; } else { mOrthoTarget = focus; } if (IsSimple()) AddKey = false; ChangeKey(mPositionKeys, mPosition, Step, AddKey); ChangeKey(mTargetPositionKeys, mTargetPosition, Step, AddKey); UpdatePosition(Step); } leocad-0.81+svn1775/common/camera.h000066400000000000000000000163271246576231200167310ustar00rootroot00000000000000#ifndef _CAMERA_H_ #define _CAMERA_H_ #include "object.h" #include "lc_math.h" #include "lc_array.h" class TiledRender; class View; #define LC_CAMERA_HIDDEN 0x0001 #define LC_CAMERA_SIMPLE 0x0002 #define LC_CAMERA_ORTHO 0x0004 #define LC_CAMERA_POSITION_SELECTED 0x0010 #define LC_CAMERA_POSITION_FOCUSED 0x0020 #define LC_CAMERA_TARGET_SELECTED 0x0040 #define LC_CAMERA_TARGET_FOCUSED 0x0080 #define LC_CAMERA_UPVECTOR_SELECTED 0x0100 #define LC_CAMERA_UPVECTOR_FOCUSED 0x0200 #define LC_CAMERA_SELECTION_MASK (LC_CAMERA_POSITION_SELECTED | LC_CAMERA_TARGET_SELECTED | LC_CAMERA_UPVECTOR_SELECTED) #define LC_CAMERA_FOCUS_MASK (LC_CAMERA_POSITION_FOCUSED | LC_CAMERA_TARGET_FOCUSED | LC_CAMERA_UPVECTOR_FOCUSED) enum lcViewpoint { LC_VIEWPOINT_FRONT, LC_VIEWPOINT_BACK, LC_VIEWPOINT_TOP, LC_VIEWPOINT_BOTTOM, LC_VIEWPOINT_LEFT, LC_VIEWPOINT_RIGHT, LC_VIEWPOINT_HOME }; enum lcCameraSection { LC_CAMERA_SECTION_POSITION, LC_CAMERA_SECTION_TARGET, LC_CAMERA_SECTION_UPVECTOR }; class lcCamera : public lcObject { public: lcCamera(bool Simple); lcCamera(float ex, float ey, float ez, float tx, float ty, float tz); virtual ~lcCamera(); const char* GetName() const { return m_strName; } void CreateName(const lcArray& Cameras); bool IsSimple() const { return (mState & LC_CAMERA_SIMPLE) != 0; } bool IsOrtho() const { return (mState & LC_CAMERA_ORTHO) != 0; } void SetOrtho(bool Ortho) { if (Ortho) mState |= LC_CAMERA_ORTHO; else mState &= ~LC_CAMERA_ORTHO; } virtual bool IsSelected() const { return (mState & LC_CAMERA_SELECTION_MASK) != 0; } virtual bool IsSelected(lcuint32 Section) const { switch (Section) { case LC_CAMERA_SECTION_POSITION: return (mState & LC_CAMERA_POSITION_SELECTED) != 0; break; case LC_CAMERA_SECTION_TARGET: return (mState & LC_CAMERA_TARGET_SELECTED) != 0; break; case LC_CAMERA_SECTION_UPVECTOR: return (mState & LC_CAMERA_UPVECTOR_SELECTED) != 0; break; } return false; } virtual void SetSelected(bool Selected) { if (Selected) mState |= LC_CAMERA_SELECTION_MASK; else mState &= ~(LC_CAMERA_SELECTION_MASK | LC_CAMERA_FOCUS_MASK); } virtual void SetSelected(lcuint32 Section, bool Selected) { switch (Section) { case LC_CAMERA_SECTION_POSITION: if (Selected) mState |= LC_CAMERA_POSITION_SELECTED; else mState &= ~(LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED); break; case LC_CAMERA_SECTION_TARGET: if (Selected) mState |= LC_CAMERA_TARGET_SELECTED; else mState &= ~(LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED); break; case LC_CAMERA_SECTION_UPVECTOR: if (Selected) mState |= LC_CAMERA_UPVECTOR_SELECTED; else mState &= ~(LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED); break; } } virtual bool IsFocused() const { return (mState & LC_CAMERA_FOCUS_MASK) != 0; } virtual bool IsFocused(lcuint32 Section) const { switch (Section) { case LC_CAMERA_SECTION_POSITION: return (mState & LC_CAMERA_POSITION_FOCUSED) != 0; break; case LC_CAMERA_SECTION_TARGET: return (mState & LC_CAMERA_TARGET_FOCUSED) != 0; break; case LC_CAMERA_SECTION_UPVECTOR: return (mState & LC_CAMERA_UPVECTOR_FOCUSED) != 0; break; } return false; } virtual void SetFocused(lcuint32 Section, bool Focus) { switch (Section) { case LC_CAMERA_SECTION_POSITION: if (Focus) mState |= LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED; else mState &= ~(LC_CAMERA_POSITION_SELECTED | LC_CAMERA_POSITION_FOCUSED); break; case LC_CAMERA_SECTION_TARGET: if (Focus) mState |= LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED; else mState &= ~(LC_CAMERA_TARGET_SELECTED | LC_CAMERA_TARGET_FOCUSED); break; case LC_CAMERA_SECTION_UPVECTOR: if (Focus) mState |= LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED; else mState &= ~(LC_CAMERA_UPVECTOR_SELECTED | LC_CAMERA_UPVECTOR_FOCUSED); break; } } virtual lcuint32 GetFocusSection() const { if (mState & LC_CAMERA_POSITION_FOCUSED) return LC_CAMERA_SECTION_POSITION; if (mState & LC_CAMERA_TARGET_FOCUSED) return LC_CAMERA_SECTION_TARGET; if (mState & LC_CAMERA_UPVECTOR_FOCUSED) return LC_CAMERA_SECTION_UPVECTOR; return ~0; } virtual lcVector3 GetSectionPosition(lcuint32 Section) const { switch (Section) { case LC_CAMERA_SECTION_POSITION: return mPosition; case LC_CAMERA_SECTION_TARGET: return mTargetPosition; case LC_CAMERA_SECTION_UPVECTOR: return lcMul31(lcVector3(0, 1, 0), lcMatrix44AffineInverse(mWorldView)); } return lcVector3(0.0f, 0.0f, 0.0f); } void SaveLDraw(QTextStream& Stream) const; bool ParseLDrawLine(QTextStream& Stream); public: bool IsVisible() const { return (mState & LC_CAMERA_HIDDEN) == 0; } bool IsHidden() const { return (mState & LC_CAMERA_HIDDEN) != 0; } void SetHidden(bool Hidden) { if (Hidden) mState |= LC_CAMERA_HIDDEN; else mState &= ~LC_CAMERA_HIDDEN; } void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey) { ChangeKey(mPositionKeys, Position, Step, AddKey); } void SetTargetPosition(const lcVector3& TargetPosition, lcStep Step, bool AddKey) { ChangeKey(mTargetPositionKeys, TargetPosition, Step, AddKey); } void SetUpVector(const lcVector3& UpVector, lcStep Step, bool AddKey) { ChangeKey(mPositionKeys, UpVector, Step, AddKey); } public: virtual void RayTest(lcObjectRayTest& ObjectRayTest) const; virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; virtual void DrawInterface(lcContext* Context, const lcMatrix44& ViewMatrix) const; void InsertTime(lcStep Start, lcStep Time); void RemoveTime(lcStep Start, lcStep Time); bool FileLoad(lcFile& file); void Select(bool bSelecting, bool bFocus, bool bMultiple); void CompareBoundingBox(float box[6]); void UpdatePosition(lcStep Step); void CopyPosition(const lcCamera* camera); void ZoomExtents(float Aspect, const lcVector3& Center, const lcVector3* Points, int NumPoints, lcStep Step, bool AddKey); void ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, lcStep Step, bool AddKey); void Zoom(float Distance, lcStep Step, bool AddKey); void Pan(const lcVector3& Distance, lcStep Step, bool AddKey); void Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey); void Roll(float Distance, lcStep Step, bool AddKey); void Center(lcVector3& point, lcStep Step, bool AddKey); void Move(lcStep Step, bool AddKey, const lcVector3& Distance); void SetViewpoint(lcViewpoint Viewpoint); void SetFocalPoint(const lcVector3& focus, lcStep Step, bool AddKey); void StartTiledRendering(int tw, int th, int iw, int ih, float fAspect); void GetTileInfo(int* row, int* col, int* width, int* height); bool EndTile(); char m_strName[81]; float m_fovy; float m_zNear; float m_zFar; lcMatrix44 mWorldView; lcVector3 mPosition; lcVector3 mTargetPosition; lcVector3 mUpVector; lcVector3 mOrthoTarget; TiledRender* m_pTR; protected: lcArray> mPositionKeys; lcArray> mTargetPositionKeys; lcArray> mUpVectorKeys; void Initialize(); lcuint32 mState; }; #endif // _CAMERA_H_ leocad-0.81+svn1775/common/debug.cpp000066400000000000000000000034401246576231200171120ustar00rootroot00000000000000#include "lc_global.h" #include "opengl.h" #include "debug.h" #ifdef LC_DEBUG #define LC_MAX_DEBUG_LINES 100 struct LC_DEBUG_LINE { lcVector3 pt1; lcVector3 pt2; lcVector3 color; }; static LC_DEBUG_LINE DebugLines[LC_MAX_DEBUG_LINES]; static int NumDebugLines; void ClearDebugLines() { NumDebugLines = 0; } void AddDebugLine(const lcVector3& pt1, const lcVector3& pt2, const lcVector3& Color) { if (NumDebugLines == LC_MAX_DEBUG_LINES-1) return; DebugLines[NumDebugLines].pt1 = pt1; DebugLines[NumDebugLines].pt2 = pt2; DebugLines[NumDebugLines].color = Color; NumDebugLines++; } #define LC_MAX_DEBUG_QUADS 100 struct LC_DEBUG_QUAD { lcVector3 pt1; lcVector3 pt2; lcVector3 pt3; lcVector3 pt4; lcVector4 color; }; static LC_DEBUG_QUAD DebugQuads[LC_MAX_DEBUG_QUADS]; static int NumDebugQuads; void ClearDebugQuads() { NumDebugQuads = 0; } void AddDebugQuad(const lcVector3& pt1, const lcVector3& pt2, const lcVector3& pt3, const lcVector3& pt4, const lcVector4& Color) { if (NumDebugQuads == LC_MAX_DEBUG_QUADS-1) return; DebugQuads[NumDebugQuads].pt1 = pt1; DebugQuads[NumDebugQuads].pt2 = pt2; DebugQuads[NumDebugQuads].pt3 = pt3; DebugQuads[NumDebugQuads].pt4 = pt4; DebugQuads[NumDebugQuads].color = Color; NumDebugQuads++; } void RenderDebugPrimitives() { for (int i = 0; i < NumDebugLines; i++) { glVertexPointer(3, GL_FLOAT, 0, &DebugLines[i].pt1); glColor3fv((float*)&DebugLines[i].color); glDrawArrays(GL_LINES, 0, 2); } glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); for (int i = 0; i < NumDebugQuads; i++) { glVertexPointer(3, GL_FLOAT, 0, &DebugQuads[i].pt1); glColor4fv((float*)&DebugQuads[i].color); glDrawArrays(GL_QUADS, 0, 4); } glDisable(GL_BLEND); glDepthMask(GL_TRUE); } #endif // LC_DEBUG leocad-0.81+svn1775/common/debug.h000066400000000000000000000006371246576231200165640ustar00rootroot00000000000000#ifndef _DEBUG_H_ #define _DEBUG_H_ #ifdef LC_DEBUG #include "lc_math.h" void RenderDebugPrimitives(); void AddDebugLine(const lcVector3& pt1, const lcVector3& pt2, const lcVector3& Color); void ClearDebugLines(); void AddDebugQuad(const lcVector3& pt1, const lcVector3& pt2, const lcVector3& pt3, const lcVector3& pt4, const lcVector4& Color); void ClearDebugQuads(); #endif // LC_DEBUG #endif // _DEBUG_H_ leocad-0.81+svn1775/common/group.cpp000066400000000000000000000024341246576231200171620ustar00rootroot00000000000000#include "lc_global.h" #include #include "group.h" #include "lc_file.h" lcGroup::lcGroup() { mGroup = NULL; } lcGroup::~lcGroup() { } void lcGroup::FileLoad(lcFile* File) { lcint32 GroupIndex; File->ReadU8(); File->ReadBuffer(m_strName, 65); File->ReadVector3(); File->ReadS32(&GroupIndex, 1); mGroup = (lcGroup*)(long)GroupIndex; } void lcGroup::FileSave(lcFile* File, const lcArray& Groups) { lcuint8 Version = 1; // LeoCAD 0.60 File->WriteU8(Version); File->WriteBuffer(m_strName, 65); File->WriteVector3(lcVector3(0.0f, 0.0f, 0.0f)); lcint32 GroupIndex = Groups.FindIndex(mGroup); File->WriteS32(&GroupIndex, 1); } void lcGroup::CreateName(const lcArray& Groups) { if (m_strName[0]) { bool Found = false; for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++) { if (!strcmp(Groups[GroupIdx]->m_strName, m_strName)) { Found = true; break; } } if (!Found) return; } int i, max = 0; const char* Prefix = "Group "; for (int GroupIdx = 0; GroupIdx < Groups.GetSize(); GroupIdx++) if (strncmp(Groups[GroupIdx]->m_strName, Prefix, strlen(Prefix)) == 0) if (sscanf(Groups[GroupIdx]->m_strName + strlen(Prefix), " %d", &i) == 1) if (i > max) max = i; sprintf(m_strName, "%s %d", Prefix, max+1); } leocad-0.81+svn1775/common/group.h000066400000000000000000000006761246576231200166350ustar00rootroot00000000000000#ifndef _GROUP_H_ #define _GROUP_H_ #include "lc_array.h" #define LC_MAX_GROUP_NAME 64 class lcGroup { public: lcGroup(); ~lcGroup(); lcGroup* GetTopGroup() { return mGroup ? mGroup->GetTopGroup() : this; } void FileLoad(lcFile* File); void FileSave(lcFile* File, const lcArray& Groups); void CreateName(const lcArray& Groups); lcGroup* mGroup; char m_strName[LC_MAX_GROUP_NAME + 1]; }; #endif // _GROUP_H_ leocad-0.81+svn1775/common/image.cpp000066400000000000000000000057741246576231200171220ustar00rootroot00000000000000#include "lc_global.h" #include "image.h" #include "lc_file.h" static void CopyFromQImage(const QImage& Src, Image& Dest) { bool Alpha = Src.hasAlphaChannel(); Dest.Allocate(Src.width(), Src.height(), Alpha ? LC_PIXEL_FORMAT_R8G8B8A8 : LC_PIXEL_FORMAT_R8G8B8); lcuint8* Bytes = (lcuint8*)Dest.mData; for (int y = 0; y < Dest.mHeight; y++) { for (int x = 0; x < Dest.mWidth; x++) { QRgb Pixel = Src.pixel(x, y); *Bytes++ = qRed(Pixel); *Bytes++ = qGreen(Pixel); *Bytes++ = qBlue(Pixel); if (Alpha) *Bytes++ = qAlpha(Pixel); } } } Image::Image() { mData = NULL; mWidth = 0; mHeight = 0; mFormat = LC_PIXEL_FORMAT_INVALID; } Image::~Image() { FreeData(); } int Image::GetBPP() const { switch (mFormat) { case LC_PIXEL_FORMAT_INVALID: return 0; case LC_PIXEL_FORMAT_A8: return 1; case LC_PIXEL_FORMAT_L8A8: return 2; case LC_PIXEL_FORMAT_R8G8B8: return 3; case LC_PIXEL_FORMAT_R8G8B8A8: return 4; } return 0; } bool Image::HasAlpha() const { switch (mFormat) { case LC_PIXEL_FORMAT_INVALID: return false; case LC_PIXEL_FORMAT_A8: return true; case LC_PIXEL_FORMAT_L8A8: return true; case LC_PIXEL_FORMAT_R8G8B8: return false; case LC_PIXEL_FORMAT_R8G8B8A8: return true; } return 0; } void Image::FreeData() { free(mData); mData = NULL; mWidth = 0; mHeight = 0; mFormat = LC_PIXEL_FORMAT_INVALID; } void Image::Allocate(int Width, int Height, lcPixelFormat Format) { FreeData(); mWidth = Width; mHeight = Height; mFormat = Format; mData = (unsigned char*)malloc(mWidth * mHeight * GetBPP()); } void Image::ResizePow2() { int i, shifted_x, shifted_y; shifted_x = mWidth; for (i = 0; ((i < 16) && (shifted_x != 0)); i++) shifted_x = shifted_x >> 1; shifted_x = (i != 0) ? 1 << (i-1) : 1; shifted_y = mHeight; for (i = 0; ((i < 16) && (shifted_y != 0)); i++) shifted_y = shifted_y >> 1; shifted_y = (i != 0) ? 1 << (i-1) : 1; if ((shifted_x != mWidth) || (shifted_y != mHeight)) Resize (shifted_x, shifted_y); } void Image::Resize(int width, int height) { int i, j, k, components, stx, sty; float accumx, accumy; unsigned char* bits; components = GetBPP(); bits = (unsigned char*)malloc(width * height * components); for (j = 0; j < mHeight; j++) { accumy = (float)height*j/(float)mHeight; sty = (int)floor(accumy); for (i = 0; i < mWidth; i++) { accumx = (float)width*i/(float)mWidth; stx = (int)floor(accumx); for (k = 0; k < components; k++) bits[(stx+sty*width)*components+k] = mData[(i+j*mWidth)*components+k]; } } free(mData); mData = bits; mWidth = width; mHeight = height; } bool Image::FileLoad(lcMemFile& File) { QImage Image; unsigned char* Buffer = File.mBuffer + File.mPosition; int BufferLength = File.mFileSize - File.mPosition; if (!Image.loadFromData(Buffer, BufferLength)) return false; CopyFromQImage(Image, *this); return true; } bool Image::FileLoad(const char* FileName) { QImage Image; if (!Image.load(FileName)) return false; CopyFromQImage(Image, *this); return true; } leocad-0.81+svn1775/common/image.h000066400000000000000000000013471246576231200165570ustar00rootroot00000000000000#ifndef _IMAGE_H_ #define _IMAGE_H_ // Image Options #define LC_IMAGE_TRANSPARENT 0x2000 #define LC_IMAGE_MASK 0x7000 enum LC_IMAGE_FORMAT { LC_IMAGE_BMP, LC_IMAGE_JPG, LC_IMAGE_PNG }; enum lcPixelFormat { LC_PIXEL_FORMAT_INVALID, LC_PIXEL_FORMAT_A8, LC_PIXEL_FORMAT_L8A8, LC_PIXEL_FORMAT_R8G8B8, LC_PIXEL_FORMAT_R8G8B8A8 }; class Image { public: Image(); virtual ~Image(); int GetBPP() const; bool HasAlpha() const; bool FileLoad(lcMemFile& File); bool FileLoad(const char* FileName); void Resize(int Width, int Height); void ResizePow2(); void Allocate(int Width, int Height, lcPixelFormat Format); void FreeData(); int mWidth; int mHeight; lcPixelFormat mFormat; unsigned char* mData; }; #endif // _IMAGE_H_ leocad-0.81+svn1775/common/lc_application.cpp000066400000000000000000000332641246576231200210140ustar00rootroot00000000000000#include "lc_global.h" #include #include "lc_application.h" #include "lc_colors.h" #include "lc_library.h" #include "lc_profile.h" #include "system.h" #include "opengl.h" #include "project.h" #include "image.h" #include "lc_mainwindow.h" #include "lc_shortcuts.h" #include "view.h" lcApplication* g_App; void lcPreferences::LoadDefaults() { mFixedAxes = lcGetProfileInt(LC_PROFILE_FIXED_AXES); mMouseSensitivity = lcGetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY); mLightingMode = (lcLightingMode)lcGetProfileInt(LC_PROFILE_LIGHTING_MODE); mDrawAxes = lcGetProfileInt(LC_PROFILE_DRAW_AXES); mDrawEdgeLines = lcGetProfileInt(LC_PROFILE_DRAW_EDGE_LINES); mLineWidth = lcGetProfileFloat(LC_PROFILE_LINE_WIDTH); mDrawGridStuds = lcGetProfileInt(LC_PROFILE_GRID_STUDS); mGridStudColor = lcGetProfileInt(LC_PROFILE_GRID_STUD_COLOR); mDrawGridLines = lcGetProfileInt(LC_PROFILE_GRID_LINES); mGridLineSpacing = lcGetProfileInt(LC_PROFILE_GRID_LINE_SPACING); mGridLineColor = lcGetProfileInt(LC_PROFILE_GRID_LINE_COLOR); } void lcPreferences::SaveDefaults() { lcSetProfileInt(LC_PROFILE_FIXED_AXES, mFixedAxes); lcSetProfileInt(LC_PROFILE_MOUSE_SENSITIVITY, mMouseSensitivity); lcSetProfileInt(LC_PROFILE_LIGHTING_MODE, mLightingMode); lcSetProfileInt(LC_PROFILE_DRAW_AXES, mDrawAxes); lcSetProfileInt(LC_PROFILE_DRAW_EDGE_LINES, mDrawEdgeLines); lcSetProfileFloat(LC_PROFILE_LINE_WIDTH, mLineWidth); lcSetProfileInt(LC_PROFILE_GRID_STUDS, mDrawGridStuds); lcSetProfileInt(LC_PROFILE_GRID_STUD_COLOR, mGridStudColor); lcSetProfileInt(LC_PROFILE_GRID_LINES, mDrawGridLines); lcSetProfileInt(LC_PROFILE_GRID_LINE_SPACING, mGridLineSpacing); lcSetProfileInt(LC_PROFILE_GRID_LINE_COLOR, mGridLineColor); } lcApplication::lcApplication() { mProject = NULL; mLibrary = NULL; mClipboard = NULL; mPreferences.LoadDefaults(); } lcApplication::~lcApplication() { delete mProject; delete mLibrary; } void lcApplication::SetProject(Project* Project) { delete mProject; mProject = Project; const lcArray& Views = gMainWindow->GetViews(); for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++) Views[ViewIdx]->SetModel(lcGetActiveModel()); lcGetPiecesLibrary()->RemoveTemporaryPieces(); lcGetActiveModel()->UpdateInterface(); gMainWindow->UpdateAllViews(); } void lcApplication::SetClipboard(const QByteArray& Clipboard) { mClipboard = Clipboard; gMainWindow->UpdatePaste(!mClipboard.isEmpty()); } void lcApplication::ExportClipboard(const QByteArray& Clipboard) { QMimeData* MimeData = new QMimeData(); MimeData->setData("application/vnd.leocad-clipboard", Clipboard); QApplication::clipboard()->setMimeData(MimeData); SetClipboard(Clipboard); } void lcApplication::GetFileList(const char* Path, lcArray& FileList) { QDir Dir(Path); Dir.setFilter(QDir::Files | QDir::Hidden | QDir::Readable); FileList.RemoveAll(); QStringList Files = Dir.entryList(); for (int FileIdx = 0; FileIdx < Files.size(); FileIdx++) { QString AbsolutePath = Dir.absoluteFilePath(Files[FileIdx]); FileList.Add(AbsolutePath.toLocal8Bit().data()); } } bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath) { if (mLibrary == NULL) mLibrary = new lcPiecesLibrary(); if (LibPath && LibPath[0]) return mLibrary->Load(LibPath, LibraryCachePath); char* EnvPath = getenv("LEOCAD_LIB"); if (EnvPath && EnvPath[0]) { return mLibrary->Load(EnvPath, LibraryCachePath); } QString CustomPath = lcGetProfileString(LC_PROFILE_PARTS_LIBRARY); if (!CustomPath.isEmpty()) return mLibrary->Load(CustomPath.toLatin1().constData(), LibraryCachePath); // todo: qstring if (LibraryInstallPath && LibraryInstallPath[0]) { char LibraryPath[LC_MAXPATH]; strcpy(LibraryPath, LibraryInstallPath); int i = strlen(LibraryPath) - 1; if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/')) strcat(LibraryPath, "/"); strcat(LibraryPath, "library.bin"); if (mLibrary->Load(LibraryPath, LibraryCachePath)) { mLibrary->SetOfficialPieces(); return true; } } if (LDrawPath && LDrawPath[0]) { char LibraryPath[LC_MAXPATH]; strcpy(LibraryPath, LDrawPath); int i = strlen(LibraryPath) - 1; if ((LibraryPath[i] != '\\') && (LibraryPath[i] != '/')) strcat(LibraryPath, "/"); if (mLibrary->Load(LibraryPath, LibraryCachePath)) return true; } return false; } void lcApplication::ParseIntegerArgument(int* CurArg, int argc, char* argv[], int* Value) { if (argc > (*CurArg + 1)) { (*CurArg)++; int val; if ((sscanf(argv[(*CurArg)], "%d", &val) == 1) && (val > 0)) *Value = val; else printf("Invalid value specified for the %s argument.", argv[(*CurArg) - 1]); } else { *Value = 0; printf("Not enough parameters for the %s argument.", argv[(*CurArg) - 1]); } } void lcApplication::ParseStringArgument(int* CurArg, int argc, char* argv[], char** Value) { if (argc > (*CurArg + 1)) { (*CurArg)++; *Value = argv[(*CurArg)]; } else { printf("No path specified after the %s argument.", argv[(*CurArg) - 1]); } } bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstallPath, const char* LDrawPath, const char* LibraryCachePath) { char* LibPath = NULL; // Image output options. bool SaveImage = false; bool SaveWavefront = false; // bool ImageHighlight = false; int ImageWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH); int ImageHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT); lcStep ImageStart = 0; lcStep ImageEnd = 0; char* ImageName = NULL; char* ProjectName = NULL; char* WavefrontName = NULL; // Parse the command line arguments. for (int i = 1; i < argc; i++) { char* Param = argv[i]; if (Param[0] == '-') { if ((strcmp(Param, "-l") == 0) || (strcmp(Param, "--libpath") == 0)) { ParseStringArgument(&i, argc, argv, &LibPath); } else if ((strcmp(Param, "-i") == 0) || (strcmp(Param, "--image") == 0)) { SaveImage = true; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { i++; ImageName = argv[i]; } } else if ((strcmp(Param, "-w") == 0) || (strcmp(Param, "--width") == 0)) { ParseIntegerArgument(&i, argc, argv, &ImageWidth); } else if ((strcmp(Param, "-h") == 0) || (strcmp(Param, "--height") == 0)) { ParseIntegerArgument(&i, argc, argv, &ImageHeight); } else if ((strcmp(Param, "-f") == 0) || (strcmp(Param, "--from") == 0)) { int Step; ParseIntegerArgument(&i, argc, argv, &Step); ImageStart = Step; } else if ((strcmp(Param, "-t") == 0) || (strcmp(Param, "--to") == 0)) { int Step; ParseIntegerArgument(&i, argc, argv, &Step); ImageEnd = Step; } // else if (strcmp(Param, "--highlight") == 0) // ImageHighlight = true; else if ((strcmp(Param, "-wf") == 0) || (strcmp(Param, "--wavefront") == 0)) { SaveWavefront = true; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { i++; WavefrontName = argv[i]; } } else if ((strcmp(Param, "-v") == 0) || (strcmp(Param, "--version") == 0)) { printf("LeoCAD Version " LC_VERSION_TEXT "\n"); printf("Compiled " __DATE__ "\n"); return false; } else if ((strcmp(Param, "-?") == 0) || (strcmp(Param, "--help") == 0)) { printf("Usage: leocad [options] [file]\n"); printf(" [options] can be:\n"); printf(" -l, --libpath : Loads the Pieces Library from path.\n"); printf(" -i, --image : Saves a picture in the format specified by ext.\n"); printf(" -w, --width : Sets the picture width.\n"); printf(" -h, --height : Sets the picture height.\n"); printf(" -f, --from