/**********************************************************************
 *<
	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)
