pax_global_header00006660000000000000000000000064122320024070014502gustar00rootroot0000000000000052 comment=0a943964d3be648d1bfb322c2c4366e1707432ef leocad-0.80.1+svn1545b/000077500000000000000000000000001223200240700143025ustar00rootroot00000000000000leocad-0.80.1+svn1545b/common/000077500000000000000000000000001223200240700155725ustar00rootroot00000000000000leocad-0.80.1+svn1545b/common/camera.cpp000066400000000000000000000533561223200240700175420ustar00rootroot00000000000000#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" #define LC_CAMERA_SAVE_VERSION 6 // LeoCAD 0.73 static LC_OBJECT_KEY_INFO camera_key_info[LC_CK_COUNT] = { { "Camera Position", 3, LC_CK_EYE }, { "Camera Target", 3, LC_CK_TARGET }, { "Camera Up Vector", 3, LC_CK_UP } }; // ============================================================================= // CameraTarget class CameraTarget::CameraTarget(Camera *pParent) : Object(LC_OBJECT_CAMERA_TARGET) { m_pParent = pParent; /* strcpy (m_strName, pParent->GetName ()); m_strName[LC_OBJECT_NAME_LEN-8] = '\0'; strcat (m_strName, ".Target"); */ } CameraTarget::~CameraTarget() { } void CameraTarget::MinIntersectDist(lcClickLine* ClickLine) { lcVector3 Min = lcVector3(-0.2f, -0.2f, -0.2f); lcVector3 Max = lcVector3(0.2f, 0.2f, 0.2f); lcMatrix44 WorldView = ((Camera*)m_pParent)->mWorldView; WorldView.SetTranslation(lcMul30(-((Camera*)m_pParent)->mTargetPosition, WorldView)); lcVector3 Start = lcMul31(ClickLine->Start, WorldView); lcVector3 End = lcMul31(ClickLine->End, WorldView); float Dist; if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Dist, NULL) && (Dist < ClickLine->MinDist)) { ClickLine->Closest = this; ClickLine->MinDist = Dist; } } bool CameraTarget::IntersectsVolume(const lcVector4 Planes[6]) const { lcVector3 Min(-0.2f, -0.2f, -0.2f); lcVector3 Max(0.2f, 0.2f, 0.2f); // Transform the planes to local space. lcVector4 LocalPlanes[6]; lcMatrix44 WorldView = m_pParent->mWorldView; WorldView.SetTranslation(lcMul30(-m_pParent->mTargetPosition, WorldView)); for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { lcVector3 Normal = lcMul30(lcVector3(Planes[PlaneIdx][0], Planes[PlaneIdx][1], Planes[PlaneIdx][2]), WorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, Planes[PlaneIdx][3] - lcDot3(WorldView[3], Normal)); } return lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes); } void CameraTarget::Select(bool bSelecting, bool bFocus, bool bMultiple) { m_pParent->SelectTarget(bSelecting, bFocus, bMultiple); } const char* CameraTarget::GetName() const { return m_pParent->GetName(); } ///////////////////////////////////////////////////////////////////////////// // Camera construction/destruction Camera::Camera(bool Simple) : Object(LC_OBJECT_CAMERA) { Initialize(); if (Simple) m_nState |= LC_CAMERA_SIMPLE; else { mPosition = lcVector3(-10.0f, -10.0f, 5.0f); mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f); mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); ChangeKey(1, false, true, mPosition, LC_CK_EYE); ChangeKey(1, false, true, mTargetPosition, LC_CK_TARGET); ChangeKey(1, false, true, mUpVector, LC_CK_UP); ChangeKey(1, true, true, mPosition, LC_CK_EYE); ChangeKey(1, true, true, mTargetPosition, LC_CK_TARGET); ChangeKey(1, true, true, mUpVector, LC_CK_UP); UpdatePosition(1, false); } } Camera::Camera(float ex, float ey, float ez, float tx, float ty, float tz) : Object(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(); float eye[3] = { ex, ey, ez }, target[3] = { tx, ty, tz }; ChangeKey(1, false, true, eye, LC_CK_EYE); ChangeKey(1, false, true, target, LC_CK_TARGET); ChangeKey(1, false, true, UpVector, LC_CK_UP); ChangeKey(1, true, true, eye, LC_CK_EYE); ChangeKey(1, true, true, target, LC_CK_TARGET); ChangeKey(1, true, true, UpVector, LC_CK_UP); UpdatePosition(1, false); } Camera::~Camera() { delete m_pTarget; } void Camera::Initialize() { m_fovy = 30.0f; m_zNear = 1.0f; m_zFar = 500.0f; m_nState = 0; m_nType = LC_CAMERA_USER; m_pTR = NULL; memset(m_strName, 0, sizeof(m_strName)); float *values[] = { mPosition, mTargetPosition, mUpVector }; RegisterKeys(values, camera_key_info, LC_CK_COUNT); m_pTarget = new CameraTarget(this); } void Camera::CreateName(const lcArray& Cameras) { 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); } ///////////////////////////////////////////////////////////////////////////// // Camera save/load bool Camera::FileLoad(lcFile& file) { lcuint8 version, ch; version = file.ReadU8(); if (version > LC_CAMERA_SAVE_VERSION) return false; if (version > 5) if (!Object::FileLoad(file)) return false; 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(1, false, true, f, LC_CK_EYE); ChangeKey(1, true, true, f, LC_CK_EYE); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; ChangeKey(1, false, true, f, LC_CK_TARGET); ChangeKey(1, true, true, f, LC_CK_TARGET); file.ReadDoubles(d, 3); f[0] = (float)d[0]; f[1] = (float)d[1]; f[2] = (float)d[2]; ChangeKey(1, false, true, f, LC_CK_UP); ChangeKey(1, true, true, f, LC_CK_UP); } 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(step, false, true, f, LC_CK_EYE); ChangeKey(step, true, true, f, LC_CK_EYE); f[0] = (float)target[0]; f[1] = (float)target[1]; f[2] = (float)target[2]; ChangeKey(step, false, true, f, LC_CK_TARGET); ChangeKey(step, true, true, f, LC_CK_TARGET); f[0] = (float)up[0]; f[1] = (float)up[1]; f[2] = (float)up[2]; ChangeKey(step, false, true, f, LC_CK_UP); ChangeKey(step, true, true, f, LC_CK_UP); 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); ChangeKey(time, false, true, param, type); } n = file.ReadS32(); while (n--) { file.ReadU16(&time, 1); file.ReadFloats(param, 3); file.ReadU8(&type, 1); ChangeKey(time, true, true, param, type); } } file.ReadFloats(&m_fovy, 1); file.ReadFloats(&m_zFar, 1); file.ReadFloats(&m_zNear, 1); if (version < 5) { n = file.ReadS32(); if (n != 0) m_nState |= LC_CAMERA_HIDDEN; } else { m_nState = file.ReadU8(); m_nType = 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) m_nState |= LC_CAMERA_HIDDEN; } return true; } void Camera::FileSave(lcFile& file) const { file.WriteU8(LC_CAMERA_SAVE_VERSION); Object::FileSave(file); lcuint8 ch = (unsigned char)strlen(m_strName); file.WriteU8(ch); file.WriteBuffer(m_strName, ch); file.WriteFloat(m_fovy); file.WriteFloat(m_zFar); file.WriteFloat(m_zNear); // version 5 file.WriteU8(m_nState); file.WriteU8(m_nType); } ///////////////////////////////////////////////////////////////////////////// // Camera operations void Camera::Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz) { lcVector3 MoveVec(dx, dy, dz); if (IsEyeSelected()) { mPosition += MoveVec; if (!IsSimple()) ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); } if (IsTargetSelected()) { mTargetPosition += MoveVec; if (!IsSimple()) ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); } // Fix the up vector lcVector3 FrontVector(mTargetPosition - mPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); if (!IsSimple()) ChangeKey(nTime, bAnimation, bAddKey, mUpVector, LC_CK_UP); } void Camera::Select(bool bSelecting, bool bFocus, bool bMultiple) { if (bSelecting == true) { if (bFocus == true) { m_nState |= (LC_CAMERA_FOCUSED|LC_CAMERA_SELECTED); m_pTarget->Select(false, true, bMultiple); } else m_nState |= LC_CAMERA_SELECTED; if (bMultiple == false) m_pTarget->Select(false, false, bMultiple); } else { if (bFocus == true) m_nState &= ~(LC_CAMERA_FOCUSED); else m_nState &= ~(LC_CAMERA_SELECTED|LC_CAMERA_FOCUSED); } } void Camera::SelectTarget(bool bSelecting, bool bFocus, bool bMultiple) { // FIXME: the target should handle this if (bSelecting == true) { if (bFocus == true) { m_nState |= (LC_CAMERA_TARGET_FOCUSED|LC_CAMERA_TARGET_SELECTED); Select(false, true, bMultiple); } else m_nState |= LC_CAMERA_TARGET_SELECTED; if (bMultiple == false) Select(false, false, bMultiple); } else { if (bFocus == true) m_nState &= ~(LC_CAMERA_TARGET_FOCUSED); else m_nState &= ~(LC_CAMERA_TARGET_SELECTED|LC_CAMERA_TARGET_FOCUSED); } } void Camera::UpdatePosition(unsigned short nTime, bool bAnimation) { if (!IsSimple()) CalculateKeys(nTime, bAnimation); lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 SideVector = lcCross(FrontVector, mUpVector); mUpVector = lcNormalize(lcCross(SideVector, FrontVector)); mWorldView = lcMatrix44LookAt(mPosition, mTargetPosition, mUpVector); } void Camera::CopyPosition(const Camera* 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; mUpVector = camera->mUpVector; } void Camera::Render(float fLineWidth) { lcMatrix44 ViewWorld = lcMatrix44AffineInverse(mWorldView); // Draw camera. glPushMatrix(); glMultMatrixf(ViewWorld); glEnableClientState(GL_VERTEX_ARRAY); float verts[34][3] = { { 0.3f, 0.3f, 0.3f }, { -0.3f, 0.3f, 0.3f }, { -0.3f, 0.3f, 0.3f }, { -0.3f, -0.3f, 0.3f }, { -0.3f, -0.3f, 0.3f }, { 0.3f, -0.3f, 0.3f }, { 0.3f, -0.3f, 0.3f }, { 0.3f, 0.3f, 0.3f }, { 0.3f, 0.3f, -0.3f }, { -0.3f, 0.3f, -0.3f }, { -0.3f, 0.3f, -0.3f }, { -0.3f, -0.3f, -0.3f }, { -0.3f, -0.3f, -0.3f }, { 0.3f, -0.3f, -0.3f }, { 0.3f, -0.3f, -0.3f }, { 0.3f, 0.3f, -0.3f }, { 0.3f, 0.3f, 0.3f }, { 0.3f, 0.3f, -0.3f }, { -0.3f, 0.3f, 0.3f }, { -0.3f, 0.3f, -0.3f }, { -0.3f, -0.3f, 0.3f }, { -0.3f, -0.3f, -0.3f }, { 0.3f, -0.3f, 0.3f }, { 0.3f, -0.3f, -0.3f }, { -0.3f, -0.3f, -0.6f }, { -0.3f, 0.3f, -0.6f }, { 0.0f, 0.0f, -0.3f }, { -0.3f, -0.3f, -0.6f }, { 0.3f, -0.3f, -0.6f }, { 0.0f, 0.0f, -0.3f }, { 0.3f, 0.3f, -0.6f }, { 0.3f, -0.3f, -0.6f }, { 0.3f, 0.3f, -0.6f }, { -0.3f, 0.3f, -0.6f } }; if (IsEyeSelected()) { glLineWidth(2.0f); if (m_nState & LC_CAMERA_FOCUSED) lcSetColorFocused(); else lcSetColorSelected(); } else { glLineWidth(1.0f); lcSetColorCamera(); } glVertexPointer(3, GL_FLOAT, 0, verts); glDrawArrays(GL_LINES, 0, 24); glDrawArrays(GL_LINE_STRIP, 24, 10); glPopMatrix(); // Draw target. glPushMatrix(); lcMatrix44 TargetMat = ViewWorld; TargetMat.SetTranslation(mTargetPosition); glMultMatrixf(TargetMat); if (IsTargetSelected()) { glLineWidth(2.0f); if (m_nState & LC_CAMERA_TARGET_FOCUSED) lcSetColorFocused(); else lcSetColorSelected(); } else { glLineWidth(1.0f); lcSetColorCamera(); } glEnableClientState(GL_VERTEX_ARRAY); float box[24][3] = { { 0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, 0.2f }, { -0.2f, -0.2f, 0.2f }, { -0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, 0.2f }, { 0.2f, 0.2f, 0.2f }, { 0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, -0.2f }, { -0.2f, -0.2f, -0.2f }, { -0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, -0.2f }, { 0.2f, 0.2f, -0.2f }, { 0.2f, 0.2f, 0.2f }, { 0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, -0.2f }, { -0.2f, -0.2f, 0.2f }, { -0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, -0.2f } }; glVertexPointer(3, GL_FLOAT, 0, box); glDrawArrays(GL_LINES, 0, 24); glPopMatrix(); lcVector3 Line[2] = { mPosition, mTargetPosition }; glVertexPointer(3, GL_FLOAT, 0, Line); glColor4f(0.5f, 0.8f, 0.5f, 1.0f); glLineWidth(1.0f); glDrawArrays(GL_LINES, 0, 2); if (IsSelected()) { glPushMatrix(); glMultMatrixf(ViewWorld); float Dist = lcLength(mTargetPosition - mPosition); lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, 1.33f, 0.01f, Dist); Projection = lcMatrix44Inverse(Projection); glMultMatrixf(Projection); // Draw the view frustum. 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); glPopMatrix(); } glDisableClientState(GL_VERTEX_ARRAY); } void Camera::MinIntersectDist(lcClickLine* ClickLine) { lcVector3 Min = lcVector3(-0.3f, -0.3f, -0.3f); lcVector3 Max = lcVector3(0.3f, 0.3f, 0.3f); lcVector3 Start = lcMul31(ClickLine->Start, mWorldView); lcVector3 End = lcMul31(ClickLine->End, mWorldView); float Dist; if (lcBoundingBoxRayMinIntersectDistance(Min, Max, Start, End, &Dist, NULL) && (Dist < ClickLine->MinDist)) { ClickLine->Closest = this; ClickLine->MinDist = Dist; } m_pTarget->MinIntersectDist(ClickLine); } bool Camera::IntersectsVolume(const lcVector4 Planes[6]) const { lcVector3 Min(-0.3f, -0.3f, -0.3f); lcVector3 Max(0.3f, 0.3f, 0.3f); // Transform the planes to local space. lcVector4 LocalPlanes[6]; for (int PlaneIdx = 0; PlaneIdx < 6; PlaneIdx++) { lcVector3 Normal = lcMul30(Planes[PlaneIdx], mWorldView); LocalPlanes[PlaneIdx] = lcVector4(Normal, Planes[PlaneIdx][3] - lcDot3(mWorldView[3], Normal)); } return lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes); } void Camera::LoadProjection(float fAspect) { if (m_pTR != NULL) m_pTR->BeginTile(); else { glMatrixMode(GL_PROJECTION); glLoadMatrixf(lcMatrix44Perspective(m_fovy, fAspect, m_zNear, m_zFar)); /* ymax = 10;//(m_zFar-m_zNear)*tan(DTOR*m_fovy)/3; ymin = -ymax; xmin = ymin * fAspect; xmax = ymax * fAspect; znear = -60; zfar = 60; glOrtho(xmin, xmax, ymin, ymax, znear, zfar); */ } glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mWorldView); } void Camera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, unsigned short nTime, bool bAnimation, bool bAddKey) { int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 Position(mPosition + Center - mTargetPosition); lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar); mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints); mTargetPosition = Center; if (!IsSimple()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); } UpdatePosition(nTime, bAnimation); } void Camera::ZoomRegion(View* view, float Left, float Right, float Bottom, float Top, unsigned short nTime, bool bAnimation, bool bAddKey) { int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; float Aspect = (float)Viewport[2]/(float)Viewport[3]; const lcMatrix44& ModelView = mWorldView; lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar); // Unproject screen points to world space. lcVector3 Points[3] = { lcVector3((Left + Right) / 2, (Top + Bottom) / 2, 0.9f), lcVector3((float)Viewport[2] / 2.0f, (float)Viewport[3] / 2.0f, 0.9f), lcVector3((float)Viewport[2] / 2.0f, (float)Viewport[3] / 2.0f, 0.1f), }; lcUnprojectPoints(Points, 3, ModelView, Projection, Viewport); // Center camera. lcVector3 Eye = mPosition; Eye = Eye + (Points[0] - Points[1]); lcVector3 Target = mTargetPosition; Target = Target + (Points[0] - Points[1]); // Zoom in/out. float RatioX = (Right - Left) / Viewport[2]; float RatioY = (Top - Bottom) / Viewport[3]; 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()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); } UpdatePosition(nTime, bAnimation); } void Camera::DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); FrontVector.Normalize(); FrontVector *= -2.0f * dy / (21 - mouse); // TODO: option to move eye, target or both mPosition += FrontVector; mTargetPosition += FrontVector; if (!IsSimple()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); } UpdatePosition(nTime, bAnimation); } void Camera::DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 SideVector = lcNormalize(lcCross(FrontVector, mUpVector)); lcVector3 MoveVec = (SideVector * (2.0f * dx / (21 - mouse))) + (mUpVector * (-2.0f * dy / (21 - mouse))); mPosition += MoveVec; mTargetPosition += MoveVec; if (!IsSimple()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); } UpdatePosition(nTime, bAnimation); } void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey, float* center) { lcVector3 FrontVector(mPosition - mTargetPosition); lcVector3 CenterPosition(center[0], center[1], center[2]); 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]; dx = -dx; } 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(0.1f * dy / (21 - mouse))), YRot), lcMatrix44RotationZ(-0.1f * dx / (21 - mouse))); mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition; mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; mUpVector = lcMul31(mUpVector, transform); if (!IsSimple()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mUpVector, LC_CK_UP); } UpdatePosition(nTime, bAnimation); } void Camera::DoRoll(int dx, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey) { lcVector3 FrontVector(mPosition - mTargetPosition); lcMatrix44 Rotation = lcMatrix44FromAxisAngle(FrontVector, 2.0f * dx / (21 - mouse) * LC_DTOR); mUpVector = lcMul30(mUpVector, Rotation); if (!IsSimple()) ChangeKey(nTime, bAnimation, bAddKey, mUpVector, LC_CK_UP); UpdatePosition(nTime, bAnimation); } void Camera::SetViewpoint(LC_VIEWPOINT Viewpoint, unsigned short nTime, bool bAnimation, bool bAddKey) { lcVector3 Positions[] = { lcVector3( 0.0f, -50.0f, 0.0f), // LC_VIEWPOINT_FRONT lcVector3( 0.0f, 50.0f, 0.0f), // LC_VIEWPOINT_BACK lcVector3( 0.0f, 0.0f, 50.0f), // LC_VIEWPOINT_TOP lcVector3( 0.0f, 0.0f, -50.0f), // LC_VIEWPOINT_BOTTOM lcVector3( 50.0f, 0.0f, 0.0f), // LC_VIEWPOINT_LEFT lcVector3(-50.0f, 0.0f, 0.0f), // LC_VIEWPOINT_RIGHT lcVector3(-15.0f, -15.0f, 7.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); mUpVector = Ups[Viewpoint]; if (!IsSimple()) { ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); ChangeKey(nTime, bAnimation, bAddKey, mUpVector, LC_CK_UP); } UpdatePosition(nTime, bAnimation); } void Camera::StartTiledRendering(int tw, int th, int iw, int ih, float fAspect) { m_pTR = new TiledRender(); m_pTR->TileSize(tw, th, 0); m_pTR->ImageSize(iw, ih); m_pTR->Perspective(m_fovy, fAspect, m_zNear, m_zFar); } void Camera::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 Camera::EndTile() { if (m_pTR != NULL) { if (m_pTR->EndTile()) return true; delete m_pTR; m_pTR = NULL; } return false; } leocad-0.80.1+svn1545b/common/camera.h000066400000000000000000000112721223200240700171760ustar00rootroot00000000000000#ifndef _CAMERA_H_ #define _CAMERA_H_ #include "object.h" #include "lc_math.h" #include "lc_array.h" #define LC_CAMERA_HIDDEN 0x01 #define LC_CAMERA_SELECTED 0x02 #define LC_CAMERA_FOCUSED 0x04 #define LC_CAMERA_TARGET_SELECTED 0x08 #define LC_CAMERA_TARGET_FOCUSED 0x10 #define LC_CAMERA_SIMPLE 0x20 class Camera; class CameraTarget; class TiledRender; class View; enum LC_VIEWPOINT { LC_VIEWPOINT_FRONT, LC_VIEWPOINT_BACK, LC_VIEWPOINT_TOP, LC_VIEWPOINT_BOTTOM, LC_VIEWPOINT_LEFT, LC_VIEWPOINT_RIGHT, LC_VIEWPOINT_HOME }; typedef enum { LC_CAMERA_FRONT,LC_CAMERA_BACK, LC_CAMERA_TOP, LC_CAMERA_UNDER, LC_CAMERA_LEFT, LC_CAMERA_RIGHT, LC_CAMERA_MAIN, LC_CAMERA_USER } LC_CAMERA_TYPES; enum LC_CK_TYPES { LC_CK_EYE, LC_CK_TARGET, LC_CK_UP, LC_CK_COUNT }; class CameraTarget : public Object { public: CameraTarget(Camera *pParent); virtual ~CameraTarget(); public: virtual void MinIntersectDist(lcClickLine* ClickLine); virtual bool IntersectsVolume(const lcVector4 Planes[6]) const; void Select(bool bSelecting, bool bFocus, bool bMultiple); void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z) { // FIXME: move the position handling to the camera target } const char* GetName() const; Camera* GetParent() const { return m_pParent; } protected: Camera* m_pParent; }; class Camera : public Object { public: Camera(bool Simple); Camera(float ex, float ey, float ez, float tx, float ty, float tz); virtual ~Camera(); const char* GetName() const { return m_strName; } void CreateName(const lcArray& Cameras); CameraTarget* GetTarget() const { return m_pTarget; } bool IsSimple() const { return (m_nState & LC_CAMERA_SIMPLE) != 0; } public: void Hide() { m_nState = LC_CAMERA_HIDDEN; } void UnHide() { m_nState &= ~LC_CAMERA_HIDDEN; } char* GetName() { return m_strName; } bool IsSide() { return m_nType < LC_CAMERA_MAIN; } bool IsVisible() { return (m_nState & LC_CAMERA_HIDDEN) == 0; } bool IsSelected() { return (m_nState & (LC_CAMERA_SELECTED|LC_CAMERA_TARGET_SELECTED)) != 0; } bool IsEyeSelected() { return (m_nState & LC_CAMERA_SELECTED) != 0; } bool IsTargetSelected() { return (m_nState & LC_CAMERA_TARGET_SELECTED) != 0; } bool IsEyeFocused() { return (m_nState & LC_CAMERA_FOCUSED) != 0; } bool IsTargetFocused() { return (m_nState & LC_CAMERA_TARGET_FOCUSED) != 0; } /* void Select() { m_nState |= (LC_CAMERA_SELECTED|LC_CAMERA_TARGET_SELECTED); } void UnSelect() { m_nState &= ~(LC_CAMERA_SELECTED|LC_CAMERA_FOCUSED|LC_CAMERA_TARGET_SELECTED|LC_CAMERA_TARGET_FOCUSED); } void UnFocus() { m_nState &= ~(LC_CAMERA_FOCUSED|LC_CAMERA_TARGET_FOCUSED); } void FocusEye() { m_nState |= (LC_CAMERA_FOCUSED|LC_CAMERA_SELECTED); } void FocusTarget() { m_nState |= (LC_CAMERA_TARGET_FOCUSED|LC_CAMERA_TARGET_SELECTED); } */ void SelectTarget(bool bSelecting, bool bFocus, bool bMultiple); public: bool FileLoad(lcFile& file); void FileSave(lcFile& file) const; virtual void MinIntersectDist(lcClickLine* ClickLine); virtual bool IntersectsVolume(const lcVector4 Planes[6]) const; void Select(bool bSelecting, bool bFocus, bool bMultiple); void UpdatePosition(unsigned short nTime, bool bAnimation); void CopyPosition(const Camera* camera); void Render(float fLineWidth); void LoadProjection(float fAspect); void ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, unsigned short nTime, bool bAnimation, bool bAddKey); void ZoomRegion(View* view, float Left, float Right, float Bottom, float Top, unsigned short nTime, bool bAnimation, bool bAddKey); void DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey); void DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey); void DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey, float* center); void DoRoll(int dx, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey); void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z); void SetViewpoint(LC_VIEWPOINT Viewpoint, unsigned short nTime, bool bAnimation, bool bAddKey); 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; protected: void Initialize(); // Camera target CameraTarget* m_pTarget; // Attributes unsigned char m_nState; unsigned char m_nType; TiledRender* m_pTR; }; #endif // _CAMERA_H_ leocad-0.80.1+svn1545b/common/curve.cpp000066400000000000000000000464761223200240700174430ustar00rootroot00000000000000#include "lc_global.h" #if 0 #include "lc_math.h" #include "lc_colors.h" #include #include #include "globals.h" #include "curve.h" #include "opengl.h" #define LC_CURVE_SAVE_VERSION 1 // LeoCAD 0.73 #define LC_CURVE_POINT_SAVE_VERSION 1 // LeoCAD 0.73 GLuint CurvePoint::m_nArrowList = 0; GLuint CurvePoint::m_nSphereList = 0; static LC_OBJECT_KEY_INFO curve_point_key_info[LC_CURVE_POINT_KEY_COUNT] = { { "Control Point Position", 3, LC_CURVE_POINT_KEY_POSITION }, { "Control Point Direction 1", 3, LC_CURVE_POINT_KEY_DIRECTION1 }, { "Control Point Direction 2", 3, LC_CURVE_POINT_KEY_DIRECTION2 }, { "Control Point Angle", 1, LC_CURVE_POINT_KEY_ANGLE } }; // ============================================================================= // CurvePoint class CurvePoint::CurvePoint (Curve *pParent) : Object (LC_OBJECT_CURVE_POINT) { m_pParent = pParent; /* FIXME strcpy (m_strName, pParent->GetName ()); m_strName[LC_OBJECT_NAME_LEN-8] = '\0'; strcat (m_strName, ".Target"); */ Initialize (); } CurvePoint::CurvePoint (Curve *pParent, const float *pos, const float *dir) : Object (LC_OBJECT_CURVE_POINT) { m_pParent = pParent; /* FIXME strcpy (m_strName, pParent->GetName ()); m_strName[LC_OBJECT_NAME_LEN-8] = '\0'; strcat (m_strName, ".Target"); */ Initialize (); float angle[1] = { 0 }; ChangeKey (1, false, true, pos, LC_CURVE_POINT_KEY_POSITION); ChangeKey (1, false, true, dir, LC_CURVE_POINT_KEY_DIRECTION1); ChangeKey (1, false, true, dir, LC_CURVE_POINT_KEY_DIRECTION2); ChangeKey (1, false, true, angle, LC_CURVE_POINT_KEY_ANGLE); ChangeKey (1, true, true, pos, LC_CURVE_POINT_KEY_POSITION); ChangeKey (1, true, true, dir, LC_CURVE_POINT_KEY_DIRECTION1); ChangeKey (1, true, true, dir, LC_CURVE_POINT_KEY_DIRECTION2); ChangeKey (1, true, true, angle, LC_CURVE_POINT_KEY_ANGLE); UpdatePosition (1, false); } void CurvePoint::Initialize () { if (m_nSphereList == 0) { m_nSphereList = glGenLists (1); glNewList (m_nSphereList, GL_COMPILE); float radius = 0.2f; int slices = 6, stacks = 6; float rho, drho, theta, dtheta; float x, y, z; int i, j, imin, imax; drho = 3.1415926536f/(float)stacks; dtheta = 2.0f*3.1415926536f/(float)slices; // draw +Z end as a triangle fan glBegin(GL_TRIANGLE_FAN); glVertex3f(0.0, 0.0, radius); for (j = 0; j <= slices; j++) { theta = (j == slices) ? 0.0f : j * dtheta; x = (float)(-sin(theta) * sin(drho)); y = (float)(cos(theta) * sin(drho)); z = (float)(cos(drho)); glVertex3f(x*radius, y*radius, z*radius); } glEnd(); imin = 1; imax = stacks-1; for (i = imin; i < imax; i++) { rho = i * drho; glBegin(GL_QUAD_STRIP); for (j = 0; j <= slices; j++) { theta = (j == slices) ? 0.0f : j * dtheta; x = (float)(-sin(theta) * sin(rho)); y = (float)(cos(theta) * sin(rho)); z = (float)(cos(rho)); glVertex3f(x*radius, y*radius, z*radius); x = (float)(-sin(theta) * sin(rho+drho)); y = (float)(cos(theta) * sin(rho+drho)); z = (float)(cos(rho+drho)); glVertex3f(x*radius, y*radius, z*radius); } glEnd(); } // draw -Z end as a triangle fan glBegin(GL_TRIANGLE_FAN); glVertex3f(0.0, 0.0, -radius); rho = 3.1415926536f - drho; for (j = slices; j >= 0; j--) { theta = (j==slices) ? 0.0f : j * dtheta; x = (float)(-sin(theta) * sin(rho)); y = (float)(cos(theta) * sin(rho)); z = (float)(cos(rho)); glVertex3f(x*radius, y*radius, z*radius); } glEnd(); glEndList(); } m_nState = LC_CURVE_POINT_CONTINUOUS; float *values[] = { m_fPos, m_fDir1, m_fDir2, &m_fAngle }; RegisterKeys (values, curve_point_key_info, LC_CURVE_POINT_KEY_COUNT); } CurvePoint::~CurvePoint () { } void CurvePoint::MinIntersectDist(lcClickLine* ClickLine) { /* float dist = (float)BoundingBoxIntersectDist(ClickLine); if (dist < ClickLine->MinDist) { ClickLine->MinDist = dist; ClickLine->Closest = this; m_nLastHit = 1; } m_nLastHit = 0; // FIXME: check arrows */ } void CurvePoint::UpdatePosition (unsigned short nTime, bool bAnimation) { CalculateKeys (nTime, bAnimation); } bool CurvePoint::FileLoad(lcFile& file) { // FIXME return true; } void CurvePoint::FileSave(lcFile& file) const { // FIXME } void CurvePoint::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz) { /* if (m_nState & LC_CURVE_POINT_ARROW1_FOCUS) if (m_nState & LC_CURVE_POINT_ARROW2_FOCUS) if (m_nState & LC_CURVE_POINT_CONTINUOUS) ; */ } void CurvePoint::Select (bool bSelecting, bool bFocus, bool bMultiple) { // FIXME: select arrows, use m_nLastHit if (bSelecting == true) { m_nState |= LC_CURVE_POINT_SELECTED; if (bFocus == true) { m_nState |= LC_CURVE_POINT_FOCUSED; m_pParent->DeselectOtherPoints (this, bMultiple); } } else { if (bFocus == true) m_nState &= ~(LC_CURVE_POINT_SELECTED|LC_CURVE_POINT_FOCUSED); else m_nState &= ~(LC_CURVE_POINT_SELECTED); } } void CurvePoint::Render() { if (m_nState & LC_CURVE_POINT_FOCUSED) lcSetColorFocused(); else if (m_nState & LC_CURVE_POINT_SELECTED) lcSetColorSelected(); else lcSetColorCamera(); // FIXME: same as camera color glPushMatrix (); glTranslatef (m_fPos[0], m_fPos[1], m_fPos[2]); glCallList (m_nSphereList); // FIXME: create and use arrow display list // if (m_pPoints[i].m_nFlags & LC_CURVE_POINT_FOCUSED) { glBegin (GL_LINES); glVertex3f ( m_fDir1[0]/5, m_fDir1[1]/5, m_fDir1[2]/5); glVertex3f (-m_fDir2[0]/5, -m_fDir2[1]/5, -m_fDir2[2]/5); glEnd (); } glPopMatrix (); } // ============================================================================= // Curve class Curve::Curve () : Object (LC_OBJECT_CURVE) { Initialize (); } Curve::Curve (PieceInfo *pInfo, const float *pos, unsigned char color) : Object (LC_OBJECT_CURVE) { /* Initialize (); // FIXME: set the curve type and length based on the PieceInfo m_fLength = 5; m_nCurveType = LC_CURVE_TYPE_HOSE; m_nColor = color; float dir[3] = { 0, 20, 0 }, pos2[3] = { pos[0] + m_fLength, pos[1], pos[2] }; m_fUp0[0] = 0; m_fUp0[1] = 0; m_fUp0[2] = 1; CurvePoint *pt; pt = new CurvePoint (this, pos, dir); m_Points.Add (pt); dir[1] = 0; dir[2] = -5; pt = new CurvePoint (this, pos2, dir); m_Points.Add (pt); pos2[0] += 5; dir[2] = 5; pt = new CurvePoint (this, pos2, dir); m_Points.Add (pt); UpdatePosition (1, false); */ } Curve::~Curve () { /* for (int i = 0; i < m_Points.GetSize (); i++) delete m_Points[i]; glDeleteLists (m_nDisplayList, 1); */ } void Curve::Initialize () { m_nCurveType = (LC_CURVE_TYPE)0; m_nState = 0; m_nColor = 0; m_nDisplayList = glGenLists (1); } bool Curve::FileLoad(lcFile& file) { // FIXME return true; } void Curve::FileSave(lcFile& file) const { // FIXME } void Curve::MinIntersectDist(lcClickLine* ClickLine) { // FIXME } void Curve::UpdatePosition (unsigned short nTime, bool bAnimation) { for (int i = 0; i < m_Points.GetSize (); i++) m_Points[i]->UpdatePosition (nTime, bAnimation); glNewList (m_nDisplayList, GL_COMPILE); switch (m_nCurveType) { case LC_CURVE_TYPE_HOSE: TesselateHose (); break; } glEndList (); } void Curve::Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz) { for (int i = 0; i < m_Points.GetSize (); i++) m_Points[i]->Move (nTime, bAnimation, bAddKey, dx, dy, dz); } void Curve::Select (bool bSelecting, bool bFocus, bool bMultiple) { if (bSelecting == true) { if (bFocus == true) { m_nState |= (LC_CURVE_SELECTED|LC_CURVE_FOCUSED); for (int i = 0; i < m_Points.GetSize (); i++) m_Points[i]->Select (false, true, bMultiple); } else m_nState |= LC_CURVE_SELECTED; } else { if (bFocus == true) m_nState &= ~(LC_CURVE_SELECTED|LC_CURVE_FOCUSED); else m_nState &= ~(LC_CURVE_SELECTED); for (int i = 0; i < m_Points.GetSize (); i++) m_Points[i]->Select (false, bFocus, bMultiple); } } void Curve::DeselectOtherPoints (CurvePoint *pSender, bool bFocusOnly) { CurvePoint *pt; for (int i = 0; i < m_Points.GetSize (); i++) { pt = m_Points[i]; if (pt != pSender) pt->Select (false, bFocusOnly, true); } } /* void Curve::TesselateHose () { float x, y, z, t, t2, t3, cx[4], cy[4], cz[4]; const float *p1, *p2, *r1, *r2, *u1, *u2; glEnableClientState (GL_VERTEX_ARRAY); for (unsigned int i = 0; i < m_Points.GetSize () - 1; i++) { p1 = m_Points[i]->GetPosition (); p2 = m_Points[i+1]->GetPosition (); r1 = m_Points[i]->GetDirection1 (); r2 = m_Points[i+1]->GetDirection2 (); u1 = m_Points[i]->GetUpVector (); u2 = m_Points[i+1]->GetUpVector (); cx[0] = 2*p1[0] - 2*p2[0] + r1[0] + r2[0]; cx[1] = -3*p1[0] + 3*p2[0] - 2*r1[0] - r2[0]; cx[2] = r1[0]; cx[3] = p1[0]; cy[0] = 2*p1[1] - 2*p2[1] + r1[1] + r2[1]; cy[1] = -3*p1[1] + 3*p2[1] - 2*r1[1] - r2[1]; cy[2] = r1[1]; cy[3] = p1[1]; cz[0] = 2*p1[2] - 2*p2[2] + r1[2] + r2[2]; cz[1] = -3*p1[2] + 3*p2[2] - 2*r1[2] - r2[2]; cz[2] = r1[2]; cz[3] = p1[2]; int steps1 = 16, steps2 = 6, j, k; float* verts = (float*)malloc ((steps1+1) * steps2 * 3 * sizeof (float)); float a, b, c; float ux, uy, uz; for (t = 0, j = 0; j <= steps1; j++, t += 1.0f/steps1) { t2 = t*t; t3 = t2*t; // position x = cx[0]*t3 + cx[1]*t2 + cx[2]*t + cx[3]; y = cy[0]*t3 + cy[1]*t2 + cy[2]*t + cy[3]; z = cz[0]*t3 + cz[1]*t2 + cz[2]*t + cz[3]; // tangent a = 3*cx[0]*t2 + 2*cx[1]*t + cx[2]; b = 3*cy[0]*t2 + 2*cy[1]*t + cy[2]; c = 3*cz[0]*t2 + 2*cz[1]*t + cz[2]; // gradient ux = 6*cx[0]*t + 2*cx[1]; uy = 6*cy[0]*t + 2*cy[1]; uz = 6*cz[0]*t + 2*cz[1]; Vector side, front (a, b, c); Vector up (ux, uy, uz); side.Cross (front, up); up.Cross (side, front); up.Normalize (); front.Normalize (); side.Normalize (); float f[16]; #define M(row,col) f[col*4+row] M(0,0) = side[0]; M(0,1) = up[0]; M(0,2) = front[0]; M(0,3) = x; M(1,0) = side[1]; M(1,1) = up[1]; M(1,2) = front[1]; M(1,3) = y; M(2,0) = side[2]; M(2,1) = up[2]; M(2,2) = front[2]; M(2,3) = z; M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0; #undef M float v[3]; Matrix m; m.FromFloat (f); for (int k = 0; k < steps2; k++) { float *o = &verts[(j*steps2+k)*3]; v[0] = cos (2.0 * M_PI * k / steps2) * 0.15f; v[1] = sin (2.0 * M_PI * k / steps2) * 0.15f; v[2] = 0; m.TransformPoint (o, v); glVertex3fv (o); } } GLuint *index = (GLuint*)malloc (2 * (steps2+1) * sizeof (GLuint)); glVertexPointer (3, GL_FLOAT, 0, verts); for (j = 0; j < steps1; j++) { for (k = 0; k < steps2; k++) { index[k*2] = j*steps2+k; index[k*2+1] = (j+1)*steps2+k; } index[k*2] = index[0]; index[k*2+1] = index[1]; glDrawElements (GL_TRIANGLE_STRIP, 2*(steps2+1), GL_UNSIGNED_INT, index); } free (index); free (verts); } } */ void Curve::TesselateHose () { float x, y, z, t, t2, t3, cx[4], cy[4], cz[4]; const float *p1, *p2, *r1, *r2; float u[3] = { m_fUp0[0], m_fUp0[1], m_fUp0[2] }; int steps1 = 16, steps2 = 6, j, k; float* verts = (float*)malloc ((steps1+1) * steps2 * 3 * sizeof (float)); float a, b, c; glEnableClientState (GL_VERTEX_ARRAY); glVertexPointer (3, GL_FLOAT, 0, verts); for (int i = 0; i < m_Points.GetSize () - 1; i++) { float a1, a2, angle_step; // axial rotation p1 = m_Points[i]->GetPosition (); p2 = m_Points[i+1]->GetPosition (); r1 = m_Points[i]->GetDirection1 (); r2 = m_Points[i+1]->GetDirection2 (); a1 = m_Points[i]->GetAngle (); a2 = m_Points[i+1]->GetAngle (); angle_step = (a2 - a1) / steps1; if (fabs (angle_step) < 0.01f) angle_step = 0; cx[0] = 2*p1[0] - 2*p2[0] + r1[0] + r2[0]; cx[1] = -3*p1[0] + 3*p2[0] - 2*r1[0] - r2[0]; cx[2] = r1[0]; cx[3] = p1[0]; cy[0] = 2*p1[1] - 2*p2[1] + r1[1] + r2[1]; cy[1] = -3*p1[1] + 3*p2[1] - 2*r1[1] - r2[1]; cy[2] = r1[1]; cy[3] = p1[1]; cz[0] = 2*p1[2] - 2*p2[2] + r1[2] + r2[2]; cz[1] = -3*p1[2] + 3*p2[2] - 2*r1[2] - r2[2]; cz[2] = r1[2]; cz[3] = p1[2]; for (t = 0, j = 0; j <= steps1; j++, t += 1.0f/steps1) { t2 = t*t; t3 = t2*t; // position x = cx[0]*t3 + cx[1]*t2 + cx[2]*t + cx[3]; y = cy[0]*t3 + cy[1]*t2 + cy[2]*t + cy[3]; z = cz[0]*t3 + cz[1]*t2 + cz[2]*t + cz[3]; // tangent a = 3*cx[0]*t2 + 2*cx[1]*t + cx[2]; b = 3*cy[0]*t2 + 2*cy[1]*t + cy[2]; c = 3*cz[0]*t2 + 2*cz[1]*t + cz[2]; lcVector3 SideVector, FrontVector(a, b, c); lcVector3 UpVector(u[0], u[1], u[2]); SideVector = lcCross(FrontVector, UpVector); UpVector = lcCross(SideVector, FrontVector); UpVector.Normalize(); FrontVector.Normalize(); SideVector.Normalize(); if (angle_step != 0) { // Matrix rot; // rot.FromAxisAngle(FrontVector, angle_step); // rot.TransformPoint(u, UpVector); } // else // UpVector.ToFloat(u); lcMatrix44 m(lcVector4(SideVector, 0.0f), lcVector4(UpVector, 0.0f), lcVector4(FrontVector, 0.0f), lcVector4(x, y, z, 1.0f)); for (int k = 0; k < steps2; k++) { lcVector3 Pos((float)(cos (2.0 * LC_PI * k / steps2) * 0.15), (float)(sin (2.0 * LC_PI * k / steps2) * 0.15), 0.0f); Pos = lcMul31(Pos, m); verts[(j*steps2+k)*3+0] = Pos[0]; verts[(j*steps2+k)*3+1] = Pos[1]; verts[(j*steps2+k)*3+2] = Pos[2]; } } GLuint *index = (GLuint*)malloc (2 * (steps2+1) * sizeof (GLuint)); for (j = 0; j < steps1; j++) { for (k = 0; k < steps2; k++) { index[k*2] = j*steps2+k; index[k*2+1] = (j+1)*steps2+k; } index[k*2] = index[0]; index[k*2+1] = index[1]; glDrawElements (GL_TRIANGLE_STRIP, 2*(steps2+1), GL_UNSIGNED_INT, index); } free (index); } free (verts); } void Curve::Render() { /* if ((m_nState & LC_CURVE_HIDDEN) != 0) return; lcSetColor(m_nColor); if (lcIsColorTranslucent(m_nColor)) { if (!pInfo->transparent) { pInfo->transparent = true; glEnable (GL_BLEND); glDepthMask (GL_FALSE); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else { if (pInfo->transparent) { pInfo->transparent = false; glDepthMask (GL_TRUE); glDisable (GL_BLEND); } } // glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glCallList (m_nDisplayList); // if (m_nState & LC_CURVE_SELECTED) { // turn off transparency to draw the control points if (pInfo->transparent) { pInfo->transparent = false; if (pInfo->transparent) { glDepthMask (GL_TRUE); glDisable (GL_BLEND); } } for (int i = 0; i < m_Points.GetSize (); i++) m_Points[i]->Render (pInfo); } */ /* if (IsSelected ()) { for (int i = 0; i < m_nNumPoints; i++) { if (m_pPoints[i].m_nFlags & LC_CURVE_POINT_FOCUSED) lcSetColorFocused(); else if (m_pPoints[i].m_nFlags & LC_CURVE_POINT_SELECTED) lcSetColorSelected(); else lcSetColorCamera(); // FIXME: same as camera color glPushMatrix (); // RenderSegment (m_pPoints[i].m_fPos, m_pPoints[i+1].m_fPos, m_pSegments[i].m_fR1, m_pSegments[i].m_fR2); glTranslatef (m_pPoints[i].m_fPos[0], m_pPoints[i].m_fPos[1], m_pPoints[i].m_fPos[2]); glCallList (m_nSphereList); if (m_pPoints[i].m_nFlags & LC_CURVE_POINT_FOCUSED) { glBegin (GL_LINES); if (i < m_nNumSegments) { glVertex3fv (m_pSegments[i].m_fR1); glVertex3f (0, 0, 0); } else if (i > 0) { glVertex3f (-m_pSegments[i-1].m_fR2[0], -m_pSegments[i-1].m_fR2[1], -m_pSegments[i-1].m_fR2[2]); glVertex3f (0, 0, 0); } glEnd (); } glPopMatrix (); } } */ /* if (m_nFlags & LC_CURVE_LOOP) { i = m_nNumPoints - 1; RenderSegment (m_pPoints[0].pos, m_pPoints[i].pos, m_pPoints[0].normal, m_pPoints[i].normal); } */ } #if 0 #define LC_CURVE_POINT_RADIUS 0.2f // ============================================================================= // Static functions #include /* // TODO: optimize static void RenderSegment (float p1[3], float p2[3], float r1[3], float r2[3]) { float x, y, z, t, t2, t3, cx[4], cy[4], cz[4]; int i; cx[0] = 2*p1[0] - 2*p2[0] + r1[0] + r2[0]; cx[1] = -3*p1[0] + 3*p2[0] - 2*r1[0] - r2[0]; cx[2] = r1[0]; cx[3] = p1[0]; cy[0] = 2*p1[1] - 2*p2[1] + r1[1] + r2[1]; cy[1] = -3*p1[1] + 3*p2[1] - 2*r1[1] - r2[1]; cy[2] = r1[1]; cy[3] = p1[1]; cz[0] = 2*p1[2] - 2*p2[2] + r1[2] + r2[2]; cz[1] = -3*p1[2] + 3*p2[2] - 2*r1[2] - r2[2]; cz[2] = r1[2]; cz[3] = p1[2]; glColor3f (1,0,0); glBegin (GL_LINE_STRIP); glVertex3f (cx[3], cy[3], cz[3]); for (t = 0, i = 0; i < 10; i++) { t += 0.1f; t2 = t*t; t3 = t2*t; x = cx[0]*t3 + cx[1]*t2 + cx[2]*t + cx[3]; y = cy[0]*t3 + cy[1]*t2 + cy[2]*t + cy[3]; z = cz[0]*t3 + cz[1]*t2 + cz[2]*t + cz[3]; glVertex3f (x, y, z); } glEnd (); glColor3f (0,0,0); float a, b, c; for (t = 0, i = 0; i <= 10; i++, t += 0.1f) { t2 = t*t; t3 = t2*t; x = cx[0]*t3 + cx[1]*t2 + cx[2]*t + cx[3]; y = cy[0]*t3 + cy[1]*t2 + cy[2]*t + cy[3]; z = cz[0]*t3 + cz[1]*t2 + cz[2]*t + cz[3]; a = 3*cx[0]*t2 + 2*cx[1]*t + cx[2]; b = 3*cy[0]*t2 + 2*cy[1]*t + cy[2]; c = 3*cz[0]*t2 + 2*cz[1]*t + cz[2]; Vector v1 (0, 0, 1); Vector v2 (a, b, c); Vector v3; v3.Cross (v1, v2); a = v1.Angle (v2); float v[3]; v3.ToFloat (v); Matrix m; m.FromAxisAngle (v, a); glBegin (GL_LINE_LOOP); for (int j = 0; j < 16; j++) { float o[3]; v[0] = cos (2.0 * M_PI * j / 16) * 0.15f; v[1] = sin (2.0 * M_PI * j / 16) * 0.15f; v[2] = 0; m.TransformPoint (o, v); glVertex3f (o[0]+x, o[1]+y, o[2]+z); } glEnd (); } } */ // ============================================================================= // Curve class void Curve::MinIntersectDist (LC_CLICKLINE* pLine) { // FIXME: Curve segments and tangent arrows for (int i = 0; i < m_nNumPoints; i++) { double dist = pLine->PointDistance (m_pPoints[i].m_fPos); if ((dist < pLine->mindist) && (dist < LC_CURVE_POINT_RADIUS)) { pLine->mindist = dist; pLine->pClosest = this; pLine->pParam = &m_pPoints[i]; } } } void Curve::SetSelection (bool bSelect, void *pParam) { Object::SetSelection (bSelect, pParam); if (pParam != NULL) { for (int i = 0; i < m_nNumPoints; i++) if (&m_pPoints[i] == pParam) { if (bSelect) m_pPoints[i].m_nState |= LC_CURVE_POINT_SELECTED; else m_pPoints[i].m_nState &= ~(LC_CURVE_POINT_SELECTED | LC_CURVE_POINT_FOCUSED); } } else { for (int i = 0; i < m_nNumPoints; i++) if (bSelect) m_pPoints[i].m_nState |= LC_CURVE_POINT_SELECTED; else m_pPoints[i].m_nState &= ~(LC_CURVE_POINT_SELECTED | LC_CURVE_POINT_FOCUSED); } } void Curve::SetFocus (bool bFocus, void *pParam) { Object::SetFocus (bFocus, pParam); if (pParam != NULL) { for (int i = 0; i < m_nNumPoints; i++) if (&m_pPoints[i] == pParam) { if (bFocus) m_pPoints[i].m_nState |= (LC_CURVE_POINT_SELECTED | LC_CURVE_POINT_FOCUSED); else m_pPoints[i].m_nState &= ~LC_CURVE_POINT_FOCUSED; } else { m_pPoints[i].m_nState &= ~LC_CURVE_POINT_FOCUSED; } } } #endif #endif // 0 leocad-0.80.1+svn1545b/common/curve.h000066400000000000000000000061221223200240700170700ustar00rootroot00000000000000#ifndef _CURVE_H_ #define _CURVE_H_ #if 0 #include "object.h" #include "opengl.h" class Curve; class CurvePoint; class PieceInfo; //#define LC_CURVE_POINT_HIDDEN 0x01 #define LC_CURVE_POINT_SELECTED 0x02 #define LC_CURVE_POINT_FOCUSED 0x04 #define LC_CURVE_POINT_ARROW1_FOCUSED 0x08 #define LC_CURVE_POINT_ARROW2_FOCUSED 0x10 #define LC_CURVE_POINT_CONTINUOUS 0x20 typedef enum { LC_CURVE_POINT_KEY_POSITION, LC_CURVE_POINT_KEY_DIRECTION1, LC_CURVE_POINT_KEY_DIRECTION2, LC_CURVE_POINT_KEY_ANGLE, LC_CURVE_POINT_KEY_COUNT } LC_CURVE_POINT_KEY_TYPES; class CurvePoint : public Object { public: // constructors / destructor CurvePoint(Curve *pParent); CurvePoint(Curve *pParent, const float *pos, const float *dir); virtual ~CurvePoint(); // object functions bool FileLoad(lcFile& file); void FileSave(lcFile& file) const; void MinIntersectDist(lcClickLine* ClickLine); bool IntersectsVolume(const lcVector4 Planes[6]) { return false; } void UpdatePosition(unsigned short nTime, bool bAnimation); void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz); void Render(); void Select(bool bSelecting, bool bFocus, bool bMultiple); // query functions Curve* GetParent() const { return m_pParent; } const float* GetPosition() const { return m_fPos; } const float* GetDirection1() const { return m_fDir1; } const float* GetDirection2() const { return m_fDir2; } float GetAngle () const { return m_fAngle; } protected: void Initialize (); Curve* m_pParent; static GLuint m_nArrowList; static GLuint m_nSphereList; unsigned char m_nState; // temporary float m_fPos[3]; float m_fDir1[3]; float m_fDir2[3]; float m_fAngle; unsigned char m_nLastHit; // FIXME: create arrow objects, ugly hack for now }; // ============================================================================= #define LC_CURVE_HIDDEN 0x01 #define LC_CURVE_SELECTED 0x02 #define LC_CURVE_FOCUSED 0x04 #define LC_CURVE_LOOP 0x10 #define LC_CURVE_FIXED_SIZE 0x20 // all the different types of curved objects typedef enum { LC_CURVE_TYPE_HOSE } LC_CURVE_TYPE; class Curve : public Object { public: // constructors / destructor Curve (); Curve (PieceInfo *pInfo, const float *pos, unsigned char color); virtual ~Curve (); // object functions bool FileLoad(lcFile& file); void FileSave(lcFile& file) const; void MinIntersectDist(lcClickLine* ClickLine); void UpdatePosition(unsigned short nTime, bool bAnimation); void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz); void Render(); void Select(bool bSelecting, bool bFocus, bool bMultiple); // implementation void DeselectOtherPoints(CurvePoint *pSender, bool bFocusOnly); protected: void Initialize (); void TesselateHose (); LC_CURVE_TYPE m_nCurveType; unsigned char m_nState; unsigned char m_nColor; float m_fLength; float m_fUp0[3]; GLuint m_nDisplayList; lcArray m_Points; }; #endif #endif // _CURVE_H_ leocad-0.80.1+svn1545b/common/debug.cpp000066400000000000000000000035611223200240700173710ustar00rootroot00000000000000#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() { glEnableClientState(GL_VERTEX_ARRAY); 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); glDisableClientState(GL_VERTEX_ARRAY); } #endif // LC_DEBUG leocad-0.80.1+svn1545b/common/debug.h000066400000000000000000000006371223200240700170370ustar00rootroot00000000000000#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.80.1+svn1545b/common/group.cpp000066400000000000000000000024221223200240700174320ustar00rootroot00000000000000// Piece group // #include "lc_global.h" #include #include "group.h" #include "lc_file.h" ///////////////////////////////////////////////////////////////////////////// // Group construction/destruction Group::Group() { m_pGroup = NULL; m_pNext = NULL; } Group::~Group() { } Group* Group::GetTopGroup() { return m_pGroup ? m_pGroup->GetTopGroup() : this; } void Group::SetGroup(Group* pGroup) { if (pGroup == this) return; if (m_pGroup != NULL && m_pGroup != (Group*)-1) m_pGroup->SetGroup(pGroup); else m_pGroup = pGroup; } void Group::UnGroup(Group* pGroup) { if (m_pGroup == pGroup) m_pGroup = NULL; else if (m_pGroup != NULL) m_pGroup->UnGroup(pGroup); } void Group::FileLoad(lcFile* file) { lcuint8 version; lcint32 i; file->ReadU8(&version, 1); file->ReadBuffer(m_strName, 65); file->ReadFloats(m_fCenter, 3); file->ReadS32(&i, 1); m_pGroup = (Group*)(long)i; } void Group::FileSave(lcFile* file, Group* pGroups) { lcuint8 version = 1; // LeoCAD 0.60 lcint32 i = 0; file->WriteU8(&version, 1); file->WriteBuffer(m_strName, 65); file->WriteFloats(m_fCenter, 3); if (m_pGroup == NULL) i = -1; else { for (; pGroups; pGroups = pGroups->m_pNext) if (pGroups == m_pGroup) break; else i++; } file->WriteS32(&i, 1); } leocad-0.80.1+svn1545b/common/group.h000066400000000000000000000006731223200240700171050ustar00rootroot00000000000000#ifndef _GROUP_H_ #define _GROUP_H_ #define LC_MAX_GROUP_NAME 64 class Group { public: // void DoSaveLoad(CArchive& ar, CCADDoc* pDoc); Group(); ~Group(); void SetGroup(Group* pGroup); void UnGroup(Group* pGroup); Group* GetTopGroup(); Group* m_pNext; Group* m_pGroup; void FileLoad(lcFile* file); void FileSave(lcFile* file, Group* pGroups); char m_strName[LC_MAX_GROUP_NAME + 1]; float m_fCenter[3]; }; #endif // _GROUP_H_ leocad-0.80.1+svn1545b/common/image.cpp000066400000000000000000000047671223200240700173760ustar00rootroot00000000000000#include "lc_global.h" #include "image.h" #include "opengl.h" 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; } void Image::FromOpenGL(int Width, int Height) { Allocate(Width, Height, LC_PIXEL_FORMAT_R8G8B8A8); lcuint8* Buffer = (lcuint8*)malloc(Width * Height * 4); glPixelStorei (GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Buffer); for (int Row = 0; Row < Height; Row++) memcpy(mData + (Row * Width * 4), Buffer + ((Height - Row - 1) * Width * 4), Width * 4); free(Buffer); } leocad-0.80.1+svn1545b/common/image.h000066400000000000000000000020011223200240700170160ustar00rootroot00000000000000#ifndef _IMAGE_H_ #define _IMAGE_H_ // Image Options //#define LC_IMAGE_PROGRESSIVE 0x1000 #define LC_IMAGE_TRANSPARENT 0x2000 //#define LC_IMAGE_HIGHCOLOR 0x4000 #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 FileSave(lcMemFile& File, LC_IMAGE_FORMAT Format, bool Transparent) const; bool FileSave(const char* FileName, LC_IMAGE_FORMAT Format, bool Transparent) const; bool FileLoad(lcMemFile& File); bool FileLoad(const char* FileName); void Resize(int Width, int Height); void ResizePow2(); void FromOpenGL(int Width, int Height); void Allocate(int Width, int Height, lcPixelFormat Format); void FreeData(); int mWidth; int mHeight; lcPixelFormat mFormat; unsigned char* mData; }; #endif // _IMAGE_H_ leocad-0.80.1+svn1545b/common/lc_application.cpp000066400000000000000000000211411223200240700212560ustar00rootroot00000000000000#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" lcApplication* g_App; lcApplication::lcApplication() { mProject = NULL; m_Library = NULL; mClipboard = NULL; } lcApplication::~lcApplication() { delete mClipboard; } void lcApplication::SetClipboard(lcFile* Clipboard) { delete mClipboard; mClipboard = Clipboard; gMainWindow->UpdatePaste(mClipboard != NULL); } bool lcApplication::LoadPiecesLibrary(const char* LibPath, const char* LibraryInstallPath, const char* LibraryCachePath) { if (m_Library == NULL) m_Library = new lcPiecesLibrary(); if (LibPath && LibPath[0]) { if (m_Library->Load(LibPath, LibraryCachePath)) return true; } else { char* EnvPath = getenv("LEOCAD_LIB"); if (EnvPath && EnvPath[0]) { if (m_Library->Load(EnvPath, LibraryCachePath)) return true; } else { char CustomPath[LC_MAXPATH]; strcpy(CustomPath, lcGetProfileString(LC_PROFILE_PARTS_LIBRARY)); if (CustomPath[0]) { if (m_Library->Load(CustomPath, LibraryCachePath)) return true; } else 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 (m_Library->Load(LibraryPath, LibraryCachePath)) { m_Library->mNumOfficialPieces = m_Library->mPieces.GetSize(); 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 { 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* LibraryCachePath) { char* LibPath = NULL; // Image output options. bool SaveImage = false; bool ImageAnimation = false; bool ImageInstructions = false; bool ImageHighlight = false; int ImageWidth = lcGetProfileInt(LC_PROFILE_IMAGE_WIDTH); int ImageHeight = lcGetProfileInt(LC_PROFILE_IMAGE_HEIGHT); int ImageStart = 0; int ImageEnd = 0; char* ImageName = NULL; // File to open. char* ProjectName = 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)) { ParseIntegerArgument(&i, argc, argv, &ImageStart); } else if ((strcmp(Param, "-t") == 0) || (strcmp(Param, "--to") == 0)) { ParseIntegerArgument(&i, argc, argv, &ImageEnd); } else if (strcmp(Param, "--animation") == 0) ImageAnimation = true; else if (strcmp(Param, "--instructions") == 0) ImageInstructions = true; else if (strcmp(Param, "--highlight") == 0) ImageHighlight = true; 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