Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
837 lines
18 KiB
C++
837 lines
18 KiB
C++
/**********************************************************************
|
|
*<
|
|
FILE: CvObject.cpp
|
|
|
|
DESCRIPTION: 3dStudio Collision object implementation
|
|
|
|
CREATED BY: jkyle
|
|
|
|
HISTORY:
|
|
|
|
*> Copyright (c) 1997, All Rights Reserved.
|
|
**********************************************************************/
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "CvObject.h"
|
|
#include "polyshp.h"
|
|
#include "mw4.hpp"
|
|
#include <Stuff\StuffHeaders.hpp>
|
|
#include <adept\collisionvolume.hpp>
|
|
|
|
#pragma pack(push,8)
|
|
|
|
Stuff::OBB g_obbdeleteme;
|
|
|
|
|
|
#define MIN_ZOOM 0.0001f
|
|
#define RU_UPDATE WM_USER + 666
|
|
|
|
|
|
#define NUMVERTS 7
|
|
static Point3 arrow_side[7]=
|
|
{
|
|
Point3( 0.000000, -1.000000 , 0.00000),
|
|
Point3( 0.000000, -0.500000 , 0.40000),
|
|
Point3( 0.000000, -0.500000, 0.20000),
|
|
Point3( 0.000000, -0.000000, 0.20000),
|
|
Point3( 0.000000, -0.000000, 0.00000),
|
|
Point3( 0.000000, -0.500000, 0.00000),
|
|
Point3( 0.000000, -0.500000, 0.00000)
|
|
};
|
|
|
|
static Point3 arrow_flat[7]=
|
|
{
|
|
Point3( -0.00000, -1.000000, 0.0),
|
|
Point3( 0.400000, -0.50000, 0.0),
|
|
Point3( 0.200000, -0.50000, 0.0),
|
|
Point3( 0.200000, -0.0, 0.0),
|
|
Point3( -0.200000, -0.0, 0.0),
|
|
Point3( -0.200000, -0.50000, 0.0),
|
|
Point3( -0.400000, -0.50000, 0.0)
|
|
};
|
|
|
|
#define PARAMDESC_LENGTH 1
|
|
static ParamUIDesc descParam[] =
|
|
{
|
|
// Index 0 is the material list
|
|
// Spinner
|
|
// 3 points (x,y,z_
|
|
ParamUIDesc(
|
|
CV_SIZE,EDITTYPE_FLOAT,
|
|
IDC_EDIT_X,IDC_SPIN_X,
|
|
IDC_EDIT_Y,IDC_SPIN_Y,
|
|
IDC_EDIT_Z,IDC_SPIN_Z,
|
|
0.0,2000.0,1.0,
|
|
defaultDim)
|
|
};
|
|
/*
|
|
ParamUIDesc(
|
|
2,EDITTYPE_FLOAT,
|
|
IDC_OBB_EDIT_LOCALX2,IDC_OBB_SPIN_LOCALX2,
|
|
IDC_OBB_EDIT_LOCALY2,IDC_OBB_SPIN_LOCALY2,
|
|
IDC_OBB_EDIT_LOCALZ2,IDC_OBB_SPIN_LOCALZ2,
|
|
-200.0,200.0,1.0,
|
|
defaultDim),
|
|
ParamUIDesc(
|
|
3,EDITTYPE_FLOAT,
|
|
IDC_OBB_EDIT_LOCALRADIUS,IDC_OBB_SPIN_LOCALRADIUS,
|
|
0.0,200.0,1.0,defaultDim)
|
|
ParamUIDesc(
|
|
3,EDITTYPE_FLOAT,
|
|
IDC_OBB_EDIT_WORLDX,IDC_OBB_SPIN_WORLDX,
|
|
IDC_OBB_EDIT_WORLDY,IDC_OBB_SPIN_WORLDY,
|
|
IDC_OBB_EDIT_WORLDZ,IDC_OBB_SPIN_WORLDZ,
|
|
-200.0,200.0,1.0,
|
|
defaultDim),
|
|
ParamUIDesc(
|
|
4,EDITTYPE_FLOAT,
|
|
IDC_OBB_EDIT_WORLDX2,IDC_OBB_SPIN_WORLDX2,
|
|
IDC_OBB_EDIT_WORLDY2,IDC_OBB_SPIN_WORLDY2,
|
|
IDC_OBB_EDIT_WORLDZ2,IDC_OBB_SPIN_WORLDZ2,
|
|
-200.0,200.0,1.0,
|
|
defaultDim),
|
|
ParamUIDesc(
|
|
5,EDITTYPE_FLOAT,
|
|
IDC_OBB_EDIT_WORLDRADIUS,IDC_OBB_SPIN_WORLDRADIUS,
|
|
0.0,200.0,1.0,defaultDim),
|
|
/*ParamUIDesc(
|
|
6,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK1),
|
|
ParamUIDesc(
|
|
7,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK2),
|
|
ParamUIDesc(
|
|
8,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK3),
|
|
ParamUIDesc(
|
|
9,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK4),
|
|
ParamUIDesc(
|
|
10,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK5),
|
|
ParamUIDesc(
|
|
11,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK6),
|
|
ParamUIDesc(
|
|
12,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK7),
|
|
ParamUIDesc(
|
|
13,TYPE_SINGLECHEKBOX,IDC_OBB_CHECK8),
|
|
*/
|
|
/* ParamUIDesc(
|
|
6,TYPE_SINGLECHEKBOX,(int *)&descCheckID,8)
|
|
};
|
|
*/
|
|
|
|
#define PARAMBLOCK_LENGTH 2
|
|
|
|
//TODO: Add ParamBlockDescID's for the various parameters
|
|
static ParamBlockDescID descVer1[] = {
|
|
{ TYPE_INT, NULL, FALSE, 0}, // Material flags
|
|
{ TYPE_POINT3, NULL, FALSE, 1}
|
|
};
|
|
|
|
// #define CURRENT_DESCRIPTOR descVer1 //Not used
|
|
#define CURRENT_VERSION 1
|
|
|
|
|
|
// class variable for point class.
|
|
HWND CvObject::m_hParams = NULL;
|
|
IObjParam *CvObject::m_iObjParams;
|
|
IParamMap *CvObject::m_pmapParam = NULL;
|
|
|
|
class MyParamMapDlgProc : public ParamMapUserDlgProc
|
|
{
|
|
virtual BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
|
|
virtual void DeleteThis();
|
|
virtual void Update(TimeValue t) {};
|
|
};
|
|
static MyParamMapDlgProc g_myParamMapDlgProc;
|
|
MyParamMapDlgProc::DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_COMMAND:
|
|
{
|
|
//Handle Panel's controls
|
|
HWND hwndCtrl = (HWND)lParam;
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_LIST_MATERIAL:
|
|
{
|
|
switch (HIWORD(wParam))
|
|
{
|
|
case CBN_SELCHANGE:
|
|
{
|
|
int iSel = SendMessage(hwndCtrl,LB_GETCURSEL,0,0);
|
|
int data = SendMessage(hwndCtrl,LB_GETITEMDATA,iSel,0);
|
|
|
|
int iVal;
|
|
map->GetParamBlock()->GetValue(CV_MATERIAL,0,iVal,FOREVER);
|
|
map->GetParamBlock()->SetValue(CV_MATERIAL,t,data | (iVal & Adept::CollisionVolume::e_GoodEnough) );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case IDC_CHECK_GOODENUF:
|
|
{
|
|
switch (HIWORD(wParam))
|
|
{
|
|
case BN_CLICKED:
|
|
{
|
|
int check = SendMessage(hwndCtrl,BM_GETCHECK,0,0);
|
|
int iVal;
|
|
map->GetParamBlock()->GetValue(CV_MATERIAL,0,iVal,FOREVER);
|
|
iVal &= ~Adept::CollisionVolume::e_GoodEnough;
|
|
map->GetParamBlock()->SetValue(CV_MATERIAL,t,iVal | (check?Adept::CollisionVolume::e_GoodEnough:0) );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
void MyParamMapDlgProc::DeleteThis()
|
|
{
|
|
}
|
|
|
|
/*
|
|
BOOL CALLBACK PointParamProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
CvObject *po = (CvObject*)GetWindowLong(hWnd,GWL_USERDATA);
|
|
if (!po && msg!=WM_INITDIALOG) return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
*/
|
|
|
|
Animatable* CvObject::SubAnim(int i)
|
|
{
|
|
switch (i) {
|
|
case 0: return m_pblock; // Parameter block
|
|
default: return NULL;
|
|
}
|
|
}
|
|
|
|
TSTR CvObject::SubAnimName(int i)
|
|
|
|
{
|
|
switch (i) {
|
|
case 0: return TSTR(_T("Parameters"));
|
|
default: return TSTR(_T(""));
|
|
}
|
|
}
|
|
|
|
void CvObject::BeginEditParams(
|
|
IObjParam *ip, ULONG flags,Animatable *prev)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HINSTANCE loc_hInstance = AfxGetResourceHandle ();
|
|
|
|
m_iObjParams = ip;
|
|
if (m_pmapParam)
|
|
{
|
|
// Left over
|
|
m_pmapParam->SetParamBlock(m_pblock);
|
|
} else
|
|
{
|
|
|
|
// Gotta make a new one.
|
|
m_pmapParam = CreateCPParamMap(
|
|
descParam,PARAMDESC_LENGTH,
|
|
m_pblock,
|
|
ip,
|
|
loc_hInstance,
|
|
MAKEINTRESOURCE(IDD_CV_PANEL),
|
|
GetString(IDS_PARAMS),
|
|
0);
|
|
}
|
|
m_pmapParam->SetUserDlgProc(&g_myParamMapDlgProc);
|
|
HWND hList = GetDlgItem(m_pmapParam->GetHWnd(),IDC_LIST_MATERIAL);
|
|
if (hList)
|
|
{
|
|
int iVal;
|
|
m_pblock->GetValue(CV_MATERIAL,m_iObjParams->GetTime(),iVal,FOREVER);
|
|
|
|
int iCheck = iVal & (Adept::CollisionVolume::e_GoodEnough);
|
|
|
|
iVal &= ~Adept::CollisionVolume::e_GoodEnough;
|
|
|
|
for (int x=0;x<Adept::MaterialCount;x++)
|
|
{
|
|
int index = SendMessage(hList,LB_ADDSTRING,NULL,(LPARAM)Adept::MaterialTypeAsciiToText(x));
|
|
SendMessage(hList,LB_SETITEMDATA,index,x);
|
|
if (x==iVal)
|
|
SendMessage(hList,LB_SETCURSEL,index,0);
|
|
}
|
|
|
|
if (iCheck)
|
|
{
|
|
HWND hCheck = GetDlgItem(m_pmapParam->GetHWnd(),IDC_CHECK_GOODENUF);
|
|
SendMessage(hCheck,BM_SETCHECK,BST_CHECKED,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CvObject::EndEditParams(IObjParam *ip, ULONG flags,Animatable *next)
|
|
{
|
|
|
|
if (flags&END_EDIT_REMOVEUI )
|
|
{
|
|
DestroyCPParamMap(m_pmapParam);
|
|
m_pmapParam = NULL;
|
|
}
|
|
m_iObjParams = NULL;
|
|
}
|
|
|
|
ObjectState CvObject::Eval(TimeValue time)
|
|
{
|
|
return ObjectState(this);
|
|
}
|
|
|
|
#define BOOL_CONTROL_CLASS_ID Class_ID(0x984b8d27,0x938f3e43)
|
|
|
|
CvObject::CvObject()
|
|
{
|
|
m_suspendSnap = FALSE;
|
|
m_pblock = NULL;
|
|
// m_pParent = NULL;
|
|
//m_pNode = NULL;
|
|
MakeRefByID( FOREVER, 0, CreateParameterBlock( descVer1, PARAMBLOCK_LENGTH, CURRENT_VERSION ) );
|
|
// MakeRefByID( FOREVER, 0, CreateParameterBlock( NULL, 0, CURRENT_VERSION ) );
|
|
}
|
|
|
|
|
|
RefTargetHandle CvObject::GetReference(int i)
|
|
{
|
|
if (i==0) return m_pblock;
|
|
return NULL;
|
|
}
|
|
|
|
// This methods sets the ith reference - there are two.
|
|
void CvObject::SetReference(int i, RefTargetHandle rtarg)
|
|
{
|
|
if (i==0)
|
|
{
|
|
m_pblock = (IParamBlock *)rtarg;
|
|
}
|
|
}
|
|
|
|
int CvObjectCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
|
|
{
|
|
switch (msg)
|
|
{
|
|
case MOUSE_POINT:
|
|
case MOUSE_MOVE:
|
|
{
|
|
switch(point)
|
|
{
|
|
case 0:
|
|
m_ob->m_suspendSnap = TRUE;
|
|
m_p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
|
|
mat.SetTrans(m_p0);
|
|
break;
|
|
case 1:
|
|
// mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE));
|
|
m_p1 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
|
|
|
|
// m_ob->m_pblock->SetValue(PB_SITE_SCALE,0,Length(m_p1-m_p0));
|
|
|
|
|
|
if (msg==MOUSE_POINT)
|
|
{
|
|
m_ob->m_suspendSnap = FALSE;
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case MOUSE_ABORT:
|
|
return CREATE_ABORT;
|
|
case WM_COMMAND:
|
|
{
|
|
// int x=1;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// int x;
|
|
// x++;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static CvObjectCreateCallBack cvObjectCreateCB;
|
|
|
|
CreateMouseCallBack* CvObject::GetCreateMouseCallBack()
|
|
{
|
|
cvObjectCreateCB.SetObj(this);
|
|
return(&cvObjectCreateCB);
|
|
}
|
|
|
|
RefTargetHandle CvObject::Clone(RemapDir& remap)
|
|
{
|
|
CvObject* newob = new CvObject();
|
|
// newob->triggerCount = triggerCount;
|
|
// newob->siteScale = siteScale;
|
|
|
|
newob->ReplaceReference(0, m_pblock->Clone(remap));
|
|
|
|
return(newob);
|
|
}
|
|
|
|
|
|
|
|
|
|
RefResult CvObject::NotifyRefChanged(
|
|
Interval changeInt,
|
|
RefTargetHandle hTarget,
|
|
PartID& partID,
|
|
RefMessage message)
|
|
{
|
|
switch (message)
|
|
{
|
|
/* case REFMSG_TARGET_DELETED:
|
|
{
|
|
DeleteReference(FindRef(hTarget));
|
|
break;
|
|
}
|
|
case REFMSG_NODE_LINK:
|
|
{
|
|
if (m_pNode)
|
|
{
|
|
m_pParent = m_pNode->GetParentNode();
|
|
|
|
DeleteReference(FindRef(hTarget));
|
|
}
|
|
break;
|
|
}*/
|
|
case REFMSG_CHANGE:
|
|
{
|
|
if (m_pblock)
|
|
{
|
|
|
|
|
|
if (m_iObjParams)
|
|
{
|
|
// m_pblock->GetValue(PB_Cv_SCALE,m_iObjParams->GetTime(),siteScale, FOREVER);
|
|
|
|
}
|
|
else
|
|
{
|
|
// m_pblock->GetValue(PB_SITE_SCALE, 0,siteScale, FOREVER);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if (m_pmapParam) m_pmapParam->Invalidate();
|
|
NotifyDependents(FOREVER,PART_OBJ,REFMSG_CHANGE);
|
|
if (m_iObjParams) m_iObjParams->RedrawViews(m_iObjParams->GetTime());
|
|
|
|
break;
|
|
}
|
|
|
|
case REFMSG_GET_PARAM_DIM:
|
|
{
|
|
GetParamDim *gpd = (GetParamDim*)partID;
|
|
switch (gpd->index)
|
|
{
|
|
case 0:
|
|
default: gpd->dim = defaultDim; break;
|
|
}
|
|
return REF_STOP;
|
|
}
|
|
|
|
case REFMSG_GET_PARAM_NAME:
|
|
{
|
|
GetParamName *gpn = (GetParamName*)partID;
|
|
return REF_STOP;
|
|
}
|
|
}
|
|
|
|
|
|
return REF_SUCCEED;
|
|
}
|
|
|
|
|
|
//#define OBB_MATERIALCHUNK 0x0130
|
|
//#define SITE_SCALE_CHUNK 0x0110
|
|
//#define TRIGGER_CHUNK 0x0120
|
|
|
|
// Don't need to save anything except for TM because it is a unit box
|
|
IOResult CvObject::Load(ILoad *iload)
|
|
{
|
|
// CvStruct cv;
|
|
|
|
/* ULONG nb;
|
|
IOResult res = IO_OK;
|
|
while (IO_OK==(res=iload->OpenChunk()))
|
|
{
|
|
switch (iload->CurChunkID())
|
|
{
|
|
case OBB_CHUNK:
|
|
{
|
|
res = iload->Read(&m_cvBox,sizeof(m_cvBox),&nb);
|
|
}
|
|
}
|
|
res = iload->CloseChunk();
|
|
if (res!=IO_OK)
|
|
{
|
|
return res;
|
|
}
|
|
}
|
|
*/
|
|
return IO_OK;
|
|
}
|
|
|
|
IOResult CvObject::Save(ISave *isave)
|
|
{
|
|
// CvStruct cv;
|
|
|
|
/*ULONG nb;
|
|
isave->BeginChunk(OBB_CHUNK);
|
|
isave->Write(&m_cvBox,sizeof(m_cvBox),&nb);
|
|
isave->EndChunk();*/
|
|
return IO_OK;
|
|
}
|
|
|
|
void CvObject::SetExtendedDisplay(int flags)
|
|
{
|
|
m_extDispFlags = flags;
|
|
}
|
|
|
|
void CvObject::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
|
|
{
|
|
Matrix3 tm(1);
|
|
tm.SetTrans(inode->GetObjectTM(t).GetTrans());
|
|
Point3 vec;
|
|
if (GetParamBlock()->GetValue(CV_SIZE,t,vec,FOREVER))
|
|
{
|
|
box = GetAxisBox(vpt,tm,vec, TRUE);
|
|
}
|
|
|
|
}
|
|
|
|
void CvObject::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box )
|
|
{
|
|
Matrix3 tm;
|
|
tm = inode->GetObjectTM(t);
|
|
if(!(m_extDispFlags & EXT_DISP_ZOOM_EXT))
|
|
{
|
|
Point3 vec;
|
|
if (GetParamBlock()->GetValue(CV_SIZE,t,vec,FOREVER))
|
|
{
|
|
box = GetAxisBox(vpt,tm,vec, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
box = Box3(tm.GetTrans(), tm.GetTrans());
|
|
}
|
|
}
|
|
|
|
|
|
// From BaseObject
|
|
int CvObject::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt)
|
|
{
|
|
Matrix3 tm(1);
|
|
HitRegion hitRegion;
|
|
DWORD savedLimits;
|
|
Point3 pt(0,0,0);
|
|
|
|
GraphicsWindow *gw = vpt->getGW();
|
|
tm = inode->GetObjectTM(t);
|
|
|
|
MakeHitRegion(hitRegion, type, crossing, 4, p);
|
|
|
|
gw->setRndLimits(((savedLimits = gw->getRndLimits())|GW_PICK)&~GW_ILLUM);
|
|
gw->setHitRegion(&hitRegion);
|
|
gw->clearHitCode();
|
|
DrawAxis(vpt,tm,1.0,inode->Selected(),inode->IsFrozen());
|
|
Point3 vec;
|
|
if (GetParamBlock()->GetValue(CV_SIZE,t,vec,FOREVER))
|
|
{
|
|
if (LengthSquared(vec)<0.00001)
|
|
{
|
|
vec = Point3(1.0,1.0,1.0);
|
|
}
|
|
|
|
vec = vec * 0.5f;
|
|
Box3 b(vec*-1,vec);
|
|
DrawBox(vpt->getGW(),b);
|
|
|
|
}
|
|
|
|
vpt->getGW()->setTransform(tm);
|
|
vpt->getGW()->marker(&pt,X_MRKR);
|
|
|
|
gw->setRndLimits(savedLimits);
|
|
|
|
if((hitRegion.type != POINT_RGN) && !hitRegion.crossing)
|
|
{
|
|
return TRUE;
|
|
}
|
|
return gw->checkHitCode();
|
|
}
|
|
|
|
void CvObject::Snap(TimeValue t, INode* inode, SnapInfo *snap, IPoint2 *p, ViewExp *vpt)
|
|
{
|
|
|
|
// if(m_suspendSnap)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
Matrix3 tm = inode->GetObjectTM(t);
|
|
GraphicsWindow *gw = vpt->getGW();
|
|
|
|
gw->setTransform(tm);
|
|
|
|
Matrix3 invPlane = Inverse(snap->plane);
|
|
// Check for upside-down coordinate system in viewport
|
|
float ybias = (float)gw->getWinSizeY() - 1.0f;
|
|
|
|
// Make sure the vertex priority is active and at least as important as the best snap so far
|
|
if(snap->vertPriority > 0 && snap->vertPriority <= snap->priority)
|
|
{
|
|
Point2 fp = Point2((float)p->x, (float)p->y);
|
|
Point3 screen3;
|
|
Point2 screen2;
|
|
|
|
Point3 thePoint(0,0,0);
|
|
// If constrained to the plane, make sure this point is in it!
|
|
if(snap->snapType == SNAP_2D || snap->flags & SNAP_IN_PLANE)
|
|
{
|
|
Point3 test = thePoint * tm * invPlane;
|
|
if(fabs(test.z) > 0.0001) // Is it in the plane (within reason)?
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
//gw->transPointFWin(&thePoint,&screen3); //this is for MAX 1.2
|
|
gw->transPoint(&thePoint, &screen3);
|
|
screen3.y = ybias - screen3.y;
|
|
screen2.x = screen3.x;
|
|
screen2.y = screen3.y;
|
|
|
|
// Are we within the snap radius?
|
|
int len = (int)Length(screen2 - fp);
|
|
if(len <= snap->strength)
|
|
{
|
|
// Is this priority better than the best so far?
|
|
if(snap->vertPriority < snap->priority)
|
|
{
|
|
snap->priority = snap->vertPriority;
|
|
snap->bestWorld = thePoint * tm;
|
|
snap->bestScreen = screen2;
|
|
snap->bestDist = len;
|
|
}
|
|
else
|
|
if(len < snap->bestDist)
|
|
{
|
|
snap->priority = snap->vertPriority;
|
|
snap->bestWorld = thePoint * tm;
|
|
snap->bestScreen = screen2;
|
|
snap->bestDist = len;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int CvObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags)
|
|
{
|
|
Matrix3 tm = inode->GetObjectTM(t);
|
|
Point3 pt(0,0,0);
|
|
vpt->getGW()->setTransform(tm);
|
|
|
|
Point3 vec;
|
|
DrawAxis(vpt,tm,1.0,inode->Selected(),inode->IsFrozen());
|
|
if (GetParamBlock()->GetValue(CV_SIZE,t,vec,FOREVER))
|
|
{
|
|
|
|
if (LengthSquared(vec)<0.00001)
|
|
{
|
|
vec = Point3(1.0,1.0,1.0);
|
|
}
|
|
|
|
vec = vec * 0.5f;
|
|
Box3 b(vec*-1,vec);
|
|
DrawBox(vpt->getGW(),b);
|
|
}
|
|
|
|
|
|
if(!inode->IsFrozen())
|
|
{
|
|
vpt->getGW()->setColor(LINE_COLOR,1.0f,0.9f,0.0f);
|
|
}
|
|
vpt->getGW()->marker(&pt,X_MRKR);
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
//
|
|
// Stole this from scene.cpp
|
|
// Probably couldn't hurt to make an API...
|
|
//
|
|
//
|
|
|
|
|
|
|
|
#define ZFACT (float).005;
|
|
#define AXIS_COLOR 0.4f,0.4f,0.4f
|
|
#define SELAXIS_COLOR 1.0f,1.0f,1.0f
|
|
|
|
|
|
|
|
void CvObject::DrawAxis( ViewExp *vpt, const Matrix3 &tm, float length, BOOL sel, BOOL frozen )
|
|
{
|
|
Matrix3 tmn = tm;
|
|
int limits;
|
|
|
|
vpt->getGW()->setTransform( tmn );
|
|
|
|
limits = vpt->getGW()->getRndLimits();
|
|
|
|
if (sel)
|
|
{
|
|
vpt->getGW()->setColor( TEXT_COLOR, SELAXIS_COLOR );
|
|
vpt->getGW()->setColor( LINE_COLOR, SELAXIS_COLOR );
|
|
}
|
|
else if (!frozen)
|
|
{
|
|
vpt->getGW()->setColor( TEXT_COLOR, AXIS_COLOR );
|
|
vpt->getGW()->setColor( LINE_COLOR, AXIS_COLOR );
|
|
}
|
|
|
|
vpt->getGW()->setRndLimits( limits );
|
|
}
|
|
|
|
|
|
void CvObject::DrawBox(GraphicsWindow *gw, Box3 &box) {
|
|
Point3 pt[5];
|
|
|
|
pt[0] = box[0];
|
|
pt[1] = box[1];
|
|
pt[2] = box[3];
|
|
pt[3] = box[2];
|
|
gw->polyline(4, pt, NULL, NULL, 1, NULL);
|
|
pt[0] = box[4];
|
|
pt[1] = box[5];
|
|
pt[2] = box[7];
|
|
pt[3] = box[6];
|
|
gw->polyline(4, pt, NULL, NULL, 1, NULL);
|
|
pt[0] = box[0];
|
|
pt[1] = box[4];
|
|
gw->polyline(2, pt, NULL, NULL, 0, NULL);
|
|
pt[0] = box[1];
|
|
pt[1] = box[5];
|
|
gw->polyline(2, pt, NULL, NULL, 0, NULL);
|
|
pt[0] = box[2];
|
|
pt[1] = box[6];
|
|
gw->polyline(2, pt, NULL, NULL, 0, NULL);
|
|
pt[0] = box[3];
|
|
pt[1] = box[7];
|
|
gw->polyline(2, pt, NULL, NULL, 0, NULL);
|
|
}
|
|
|
|
|
|
Box3 CvObject::GetAxisBox(ViewExp *vpt, const Matrix3 &tm,Point3 vec,int resetTM)
|
|
{
|
|
Matrix3 tmn = tm;
|
|
|
|
float zoom;
|
|
|
|
// Get width of viewport in world units: --DS
|
|
zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
|
|
if (zoom < MIN_ZOOM) zoom = 1.0f;
|
|
|
|
if(resetTM)
|
|
{
|
|
tmn.IdentityMatrix();
|
|
}
|
|
|
|
|
|
|
|
Box3 box;
|
|
|
|
box += Point3(vec.x*0.5f, 0.0f, 0.0f) *tm;
|
|
box += Point3(0.0f, vec.y*0.5f, 0.0f) *tm;
|
|
box += Point3(0.0f, 0.0f, vec.z*0.5f) *tm;
|
|
box += Point3(-vec.x*0.5f, 0.0f, 0.0f) *tm;
|
|
box += Point3(0.0f, -vec.y*0.5f, 0.0f) *tm;
|
|
box += Point3(0.0f, 0.0f, -vec.z*0.5f) *tm;
|
|
|
|
box.EnlargeBy(10.0f/zoom);
|
|
|
|
|
|
|
|
return box;
|
|
}
|
|
|
|
/*void CvObject::CalcLocalBoundBox(int nSamples,ViewExp *vpt,Box3& box)
|
|
// nSamples must be at least 1
|
|
{
|
|
// Calculate the bounding box of the parent
|
|
if (m_pParent)
|
|
{
|
|
Object *pObject = m_pParent->GetObjectRef();
|
|
if (pObject)
|
|
{
|
|
//Interval iv = m_iObjParams->GetAnimRange();
|
|
TimeValue tStart,tEnd,tInc;
|
|
tStart = GetAnimStart();
|
|
tEnd = GetAnimEnd();
|
|
if (nSamples<1)
|
|
nSamples = 1;
|
|
tInc = (tEnd - tStart) / nSamples;
|
|
|
|
|
|
pObject->GetLocalBoundBox(tStart,m_pParent,vpt,box);
|
|
|
|
for (TimeValue t = (tStart+tInc);t<=tEnd;t+=tInc)
|
|
{
|
|
Box3 boxnew;
|
|
pObject->GetLocalBoundBox(t,m_pParent,vpt,boxnew);
|
|
box+=boxnew;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CvObject::CalcOBBChildren(INode *pNode)
|
|
{
|
|
/* if (pNode)
|
|
{
|
|
char *pName = pNode->GetName();
|
|
if (0 == strncmp(pName,"cv_",3))
|
|
{
|
|
Class_ID c1 = CVOBJECT_CLASS_ID;
|
|
Class_ID c2 = pNode->GetObjectRef()->ClassID();
|
|
if (pNode != m_pNode)
|
|
{
|
|
MakeRefByID( FOREVER, 2, pNode);
|
|
Box3 box;
|
|
pNode->GetObjectRef()->GetLocalBoundBox(0,pNode,NULL,box);
|
|
m_cvBox+=box;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int x = 0;x<pNode->NumberOfChildren();x++)
|
|
{
|
|
INode *pChild = pNode->GetChildNode(x);
|
|
CalcOBBChildren(pChild);
|
|
}
|
|
}
|
|
}*/
|
|
//}
|
|
|
|
#pragma pack(pop)
|