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.
1126 lines
25 KiB
C++
1126 lines
25 KiB
C++
#include "MAXProxyHeaders.hpp"
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
//
|
|
//############################################################################
|
|
//############################## MAXScene ###############################
|
|
//############################################################################
|
|
//
|
|
|
|
INode *CreateNode(Interface *ip,SClass_ID superID,Class_ID classid);
|
|
|
|
MAXScene::ClassData*
|
|
MAXScene::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
MAXSceneClassID,
|
|
"MAXScene",
|
|
SceneProxy::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::Destroy()
|
|
{
|
|
Check_Object(this);
|
|
Verify(referenceCount == 1);
|
|
Verify(activeChildProxies.IsEmpty());
|
|
STOP(("Not implemented"));
|
|
DetachReference();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MAXScene::MAXScene(Interface *i,const char *str):
|
|
SceneProxy(DefaultData)
|
|
{
|
|
Check_Pointer(this);
|
|
//
|
|
// keep the interface pointer on hand
|
|
//
|
|
iPointer = i;
|
|
//
|
|
// get the time of the first frame and keep it
|
|
// to evaluate the world state for everything
|
|
//
|
|
Interval total_time = iPointer->GetAnimRange();
|
|
time = total_time.Start();
|
|
proxiedScene = i->GetRootNode();
|
|
//
|
|
// load the helper arrays
|
|
//
|
|
int node_count = 0;
|
|
GetMaterials(proxiedScene,node_count);
|
|
nodeCount = node_count;
|
|
meshProxies.SetLength(nodeCount);
|
|
GetBitmaps();
|
|
Check_Object(this);
|
|
notifiedOfError = false;
|
|
Check_Pointer(str);
|
|
strHintFile = str;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MAXScene::~MAXScene()
|
|
{
|
|
Check_Object(this);
|
|
|
|
if (stateLibrary)
|
|
{
|
|
Check_Object(stateLibrary);
|
|
Verify(stateLibrary->GetReferenceCount() == 1);
|
|
stateLibrary->DetachReference();
|
|
Unregister_Object(stateLibrary);
|
|
stateLibrary = NULL;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::TestInstance() const
|
|
{
|
|
if (proxiedScene)
|
|
{
|
|
Check_Pointer(proxiedScene);
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::StateLibrary*
|
|
MAXScene::GetStateLibrary()
|
|
{
|
|
Check_Object(this);
|
|
if (!stateLibrary)
|
|
{
|
|
stateLibrary = MAXStateLibrary::MakeProxy(this);
|
|
Register_Object(stateLibrary);
|
|
}
|
|
Check_Object(stateLibrary);
|
|
return stateLibrary;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXScene::GetName(MString *name)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(name);
|
|
Check_Pointer(proxiedScene);
|
|
//
|
|
//----------------------------------------------
|
|
// Get the scene name and check the length
|
|
//----------------------------------------------
|
|
//
|
|
TCHAR *string = proxiedScene->GetName();
|
|
int len = strlen(string);
|
|
if (len != 0)
|
|
{
|
|
*name = string;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::SetName(const char* name)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(name);
|
|
Check_Pointer(proxiedScene);
|
|
TCHAR *string = (TCHAR *)name;
|
|
proxiedScene->SetName(string);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXScene::GetOBB(OBB *obb)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(obb);
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::SetOBB(const OBB &obb)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&obb);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::SetBoundingSphere(const Sphere &sphere)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&sphere);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
unsigned
|
|
MAXScene::GetChildCount()
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(proxiedScene);
|
|
return proxiedScene->NumberOfChildren();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::GroupProxy*
|
|
MAXScene::AppendNewGroupProxy()
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(this);
|
|
|
|
int time = 0;
|
|
int index = 0;
|
|
INode *child = CreateNode(iPointer,HELPER_CLASS_ID,Class_ID(DUMMY_CLASS_ID,0));
|
|
MAXGroup *proxy = MAXGroup::MakeProxy(this, NULL, child, time, index, true);
|
|
Check_Object(proxy);
|
|
return proxy;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::GroupProxy*
|
|
MAXScene::InsertNewGroupProxy(Proxies::ChildProxy *before)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(before);
|
|
Verify(!before->GetParentGroupProxy());
|
|
STOP(("Not implemented"));
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
INode *CreateNode(Interface *ip,SClass_ID superID,Class_ID classid)
|
|
{
|
|
Check_Pointer(ip);
|
|
//Object *obj = (Object*)ip->CreateInstance(GEOMOBJECT_CLASS_ID, Class_ID(TRIOBJ_CLASS_ID,0));
|
|
Object *obj = (Object*)ip->CreateInstance(superID,classid);
|
|
Check_Pointer(obj);
|
|
|
|
// Get a hold of the parameter block
|
|
//IParamArray *iParams = obj->GetParamBlock();
|
|
//Check_Pointer(iParams);
|
|
|
|
// Set the parameters
|
|
// Set to a default material
|
|
//iParams->SetValue(CV_MATERIAL,TimeValue(0),MechWarrior4::SteelMaterial);
|
|
|
|
|
|
INode *new_node = ip->CreateObjectNode(obj);
|
|
|
|
|
|
|
|
/* {
|
|
CString nodename = inode->GetName();
|
|
int index = nodename.Find("_",0);
|
|
if (index >=0)
|
|
nodename.Delete(0,index+1);
|
|
CString name = "cv_";
|
|
name += nodename;
|
|
new_node->SetName(name.GetBuffer(50));
|
|
}
|
|
*/
|
|
/*riObject *meshData;
|
|
Verify(os.obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)));
|
|
meshData = (TriObject *) os.obj->ConvertToType(0,Class_ID(TRIOBJ_CLASS_ID,
|
|
0));*/
|
|
/* meshData->mesh.buildBoundingBox();
|
|
|
|
Box3 box;
|
|
box = meshData->mesh.getBoundingBox();
|
|
Point3 pt = box.Width();
|
|
iParams->SetValue(CV_SIZE,TimeValue(0),pt);
|
|
|
|
|
|
// figure out the correct offset
|
|
|
|
Point3 offset;
|
|
offset.x = box.pmin.x - (pt.x*-0.5f);
|
|
offset.y = box.pmin.y - (pt.y*-0.5f);
|
|
offset.z = box.pmin.z - (pt.z*-0.5f);
|
|
|
|
|
|
Point3 offset_trans = inode->GetObjOffsetPos();
|
|
Quat offset_rot = inode->GetObjOffsetRot();
|
|
|
|
//SPEW(("jerryeds", "obj-'%s'", inode->GetName()));
|
|
//SPEW(("jerryeds", "qpvt - %f %f %f %f", offset_rot.x, offset_rot.y,
|
|
offset_rot.z, offset_rot.w));
|
|
//SPEW(("jerryeds", "pvt - %f %f %f", offset_trans.x, offset_trans.y,
|
|
offset_trans.z));
|
|
//SPEW(("jerryeds", "pmin - %f %f %f", box.pmin.x, box.pmin.y, box.pmin.z));
|
|
//SPEW(("jerryeds", "pmax - %f %f %f", box.pmax.x, box.pmax.y, box.pmax.z));
|
|
//SPEW(("jerryeds", "pt - %f %f %f", pt.x, pt.y, pt.z));
|
|
//SPEW(("jerryeds", "ofst - %f %f %f", offset.x, offset.y, offset.z));
|
|
|
|
offset.x += offset_trans.x;
|
|
offset.y += offset_trans.y;
|
|
offset.z += offset_trans.z;
|
|
|
|
|
|
Matrix3 node_tm;
|
|
node_tm.IdentityMatrix();
|
|
offset_rot.MakeMatrix(node_tm);
|
|
node_tm.SetTrans(offset);
|
|
|
|
|
|
//find nearest joint_ parent node..
|
|
INode *closest_parent = FindParentJoint(inode);
|
|
Check_Pointer(closest_parent);
|
|
|
|
|
|
new_node->SetNodeTM(0,node_tm);
|
|
|
|
closest_parent->AttachChild(new_node,0);
|
|
//SPEW(("jerryeds", "par-'%s'", closest_parent->GetName()));
|
|
*/
|
|
return new_node;
|
|
}
|
|
|
|
|
|
|
|
Proxies::PolygonMeshProxy*
|
|
MAXScene::AppendNewPolygonMeshProxy()
|
|
{
|
|
Check_Object(this);
|
|
INode *pNode = CreateNode(iPointer,GEOMOBJECT_CLASS_ID, Class_ID(TRIOBJ_CLASS_ID,0));
|
|
rootList.AddNode(pNode);
|
|
Proxies::StateLibrary *library = GetStateLibrary();
|
|
MAXProxies::MAXStateLibrary *maxlibrary = Cast_Object(MAXProxies::MAXStateLibrary *,library);
|
|
pNode->SetMtl(maxlibrary->GetMultiMtl());
|
|
|
|
proxiedScene->AttachChild(pNode,0);
|
|
TimeValue time = 0;
|
|
int index = 0;
|
|
MAXPolygonMesh *proxy = MAXPolygonMesh::MakeProxy(this, NULL, pNode, time, index, false);
|
|
Register_Object(proxy);
|
|
|
|
return proxy;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::PolygonMeshProxy*
|
|
MAXScene::InsertNewPolygonMeshProxy(Proxies::ChildProxy *before)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(before);
|
|
Verify(!before->GetParentGroupProxy());
|
|
STOP(("Not implemented"));
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::AppendMatchingChildProxy(Proxies::ChildProxy *child)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(child);
|
|
STOP(("Not implemented"));
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::InsertMatchingChildProxy(
|
|
Proxies::ChildProxy *child,
|
|
Proxies::ChildProxy *before
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(child);
|
|
Check_Object(before);
|
|
Verify(!before->GetParentGroupProxy());
|
|
STOP(("Not implemented"));
|
|
return NULL;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::UseFirstChildProxy()
|
|
{
|
|
Check_Object(this);
|
|
|
|
int index = IndexFirstValidElement(iPointer->GetRootNode());
|
|
|
|
#if 0
|
|
INode *root = FindRoot(iPointer->GetRootNode());
|
|
if (root)
|
|
{
|
|
return
|
|
InterpretRecord(NULL,root,0,true);
|
|
}
|
|
#else
|
|
if (index > -1)
|
|
{
|
|
return
|
|
InterpretRecord(NULL,iPointer->GetRootNode()->GetChildNode(index),index,true);
|
|
}
|
|
#endif
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::UseLastChildProxy()
|
|
{
|
|
Check_Object(this);
|
|
|
|
int index = IndexLastValidElement(iPointer->GetRootNode());
|
|
if (index > -1)
|
|
{
|
|
return
|
|
InterpretRecord(NULL,iPointer->GetRootNode()->GetChildNode(index),index,true);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::GetAmbientColor(RGBColor *color)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(color);
|
|
Interval valid;
|
|
|
|
Point3 c = iPointer->GetAmbient(time, valid);
|
|
color->red = c.x;
|
|
color->green = c.y;
|
|
color->blue = c.z;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::SetAmbientColor(const RGBColor &color)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&color);
|
|
Point3 c;
|
|
c.x = color.red;
|
|
c.y = color.green;
|
|
c.z = color.blue;
|
|
iPointer->SetAmbient(time, c);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::Close()
|
|
{
|
|
Check_Object(this);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::InterpretRecord(
|
|
MAXGroup *parent,
|
|
INode *child,
|
|
int index,
|
|
bool auto_hierarchy
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(child);
|
|
|
|
TCHAR *name = child->GetName();
|
|
|
|
if (parent)
|
|
{
|
|
TCHAR *parent_name = parent->GetProxiedGroup()->GetName();
|
|
}
|
|
|
|
|
|
//
|
|
//-------------------
|
|
// Get the child type
|
|
//-------------------
|
|
//
|
|
ObjectState os = child->EvalWorldState(time);
|
|
Proxies::ChildProxy *proxy = NULL;
|
|
|
|
if (os.obj)
|
|
{
|
|
//
|
|
//----------------------------------
|
|
// If the child is a light, make one
|
|
//----------------------------------
|
|
//
|
|
if ((os.obj->SuperClassID() == LIGHT_CLASS_ID) || (os.obj->SuperClassID() == TARGET_CLASS_ID))
|
|
{
|
|
Verify(!parent);
|
|
// DEBUG_STREAM << " Found light class and made a light proxy" << endl;
|
|
MAXLight *light = MAXLight::MakeProxy(this, parent, child,index);
|
|
Register_Object(light);
|
|
return light;
|
|
// return NULL;
|
|
}
|
|
else if (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID)
|
|
{
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// If the child is a mesh, we will need to auto-create a group between the
|
|
// current parent and the mesh's children if it has any
|
|
//------------------------------------------------------------------------
|
|
//
|
|
if (os.obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
|
|
{
|
|
if (child->NumberOfChildren()>0 && auto_hierarchy)
|
|
{
|
|
proxy = MAXGroup::MakeProxy(this, parent, child, time, index, true);
|
|
Register_Object(proxy);
|
|
return proxy;
|
|
}
|
|
bool has_children = false;
|
|
if (child->NumberOfChildren()>0)
|
|
{
|
|
has_children = true;
|
|
}
|
|
proxy = MAXPolygonMesh::MakeProxy(this, parent, child, time, index, has_children);
|
|
Register_Object(proxy);
|
|
LinearMatrix4D mat;
|
|
proxy->GetLocalToParent(&mat);
|
|
return proxy;
|
|
}
|
|
else
|
|
{
|
|
if (os.obj->CanConvertToType(Class_ID(TARGET_CLASS_ID, 0)))
|
|
{
|
|
proxy = MAXGroup::MakeProxy(this, parent, child, time, index, true);
|
|
Register_Object(proxy);
|
|
return proxy;
|
|
}
|
|
}
|
|
}
|
|
else if (os.obj->SuperClassID() == CAMERA_CLASS_ID)
|
|
{
|
|
// proxy = MAXGroup::MakeProxy(this, parent, child, time);
|
|
// Register_Object(proxy);
|
|
// return proxy;
|
|
}
|
|
else if (os.obj->SuperClassID() == SHAPE_CLASS_ID)
|
|
{
|
|
proxy = MAXGroup::MakeProxy(this, parent, child, time, index, false);
|
|
Register_Object(proxy);
|
|
return proxy;
|
|
}
|
|
else if (os.obj->SuperClassID() == HELPER_CLASS_ID)
|
|
{
|
|
//
|
|
//--------------------------------------------------------
|
|
// If this is a standard null, just make a hierarchy proxy
|
|
//--------------------------------------------------------
|
|
//
|
|
#if 0
|
|
if (os.obj->IsSubClassOf(Class_ID(DUMMY_CLASS_ID, 0)))
|
|
{
|
|
}
|
|
#endif
|
|
proxy = MAXGroup::MakeProxy(this, parent, child, time, index, false);
|
|
Register_Object(proxy);
|
|
return proxy;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::GetMaterials(INode* node, int& nodeCount)
|
|
{
|
|
nodeCount++;
|
|
|
|
// Add the nodes material to out material list
|
|
// Null entries are ignored when added...
|
|
Mtl *m = node->GetMtl();
|
|
if (m)
|
|
{
|
|
mtlList.AddMtl(m);
|
|
}
|
|
|
|
// For each child of this node, we recurse into ourselves
|
|
// and increment the counter until no more children are found.
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
GetMaterials(node->GetChildNode(c), nodeCount);
|
|
|
|
if (m)
|
|
{
|
|
int number_sub_materials = m->NumSubMtls();
|
|
for (int w=0;w<number_sub_materials;w++)
|
|
{
|
|
Mtl* sub = m->GetSubMtl(w);
|
|
mtlList.AddMtl(sub);
|
|
}
|
|
}
|
|
|
|
INode *temp = node->GetChildNode(c);
|
|
TCHAR *string = temp->GetName();
|
|
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::GetRootElements()
|
|
{
|
|
int elements = proxiedScene->NumberOfChildren();
|
|
for (int i=0;i<elements;i++)
|
|
{
|
|
if (ValidElement(proxiedScene->GetChildNode(i)))
|
|
{
|
|
rootList.AddNode(proxiedScene->GetChildNode(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MAXScene::IndexFirstValidElement(INode *node)
|
|
{
|
|
unsigned count = node->NumberOfChildren();
|
|
Proxies::ChildProxy *child = NULL;
|
|
|
|
int index = 0;
|
|
while ((index < count) && (ValidElement(node) == false))
|
|
{
|
|
if (ValidElement(node->GetChildNode(index)))
|
|
{
|
|
return index;
|
|
}
|
|
index++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MAXScene::IndexLastValidElement(INode *node)
|
|
{
|
|
unsigned count = node->NumberOfChildren();
|
|
Proxies::ChildProxy *child = NULL;
|
|
|
|
int index = count-1;
|
|
while ((index >= 0) && (ValidElement(node) == false))
|
|
{
|
|
if (ValidElement(node->GetChildNode(index)))
|
|
{
|
|
return index;
|
|
}
|
|
index--;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXScene::ValidElement(INode *node)
|
|
{
|
|
if (node == NULL) return false;
|
|
|
|
ObjectState os = node->EvalWorldState(time);
|
|
|
|
if (os.obj)
|
|
{
|
|
//
|
|
// If the child is a light, make one
|
|
//
|
|
if (os.obj->SuperClassID() == LIGHT_CLASS_ID)
|
|
{
|
|
return true;
|
|
}
|
|
else if (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID)
|
|
{
|
|
//
|
|
// If the child is a mesh, we will need to auto-create a group between the
|
|
// current parent and the mesh's children if it has any
|
|
//
|
|
if (os.obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (os.obj->SuperClassID() == CAMERA_CLASS_ID)
|
|
{
|
|
return false;
|
|
}
|
|
else if (os.obj->SuperClassID() == SHAPE_CLASS_ID)
|
|
{
|
|
return true;
|
|
}
|
|
else if (os.obj->SuperClassID() == HELPER_CLASS_ID)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::GetBitmaps()
|
|
{
|
|
int number_materials = mtlList.Count();
|
|
|
|
Texmap *tmap = NULL;
|
|
BitmapTex *texture = NULL;
|
|
|
|
for (int i=0;i<number_materials;i++)
|
|
{
|
|
Mtl* m = mtlList.GetMtl(i);
|
|
if (!m)
|
|
{
|
|
return;
|
|
}
|
|
if (m->ClassID() == Class_ID(DMTL_CLASS_ID,0))
|
|
{
|
|
for (int c=0;c<NTEXMAPS;c++)
|
|
{
|
|
//
|
|
// changed to do multitexturing
|
|
//
|
|
//tmap = m->GetSubTexmap(ID_DI);
|
|
if (c==ID_OP) continue; // skip over the opacity map cause we use it
|
|
tmap = m->GetSubTexmap(c);
|
|
if (!tmap)
|
|
{
|
|
continue;
|
|
}
|
|
if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
|
|
{
|
|
texture = (BitmapTex*)tmap;
|
|
bmpList.AddBitmap(texture);
|
|
//TCHAR *temp1 = texture->GetMapName();
|
|
}
|
|
}
|
|
}
|
|
else if (m->ClassID() == Class_ID(MULTI_CLASS_ID,0))
|
|
{
|
|
int number_sub_materials = m->NumSubMtls();
|
|
for (int w=0;w<number_sub_materials;w++)
|
|
{
|
|
Mtl* sub = m->GetSubMtl(w);
|
|
tmap = sub->GetSubTexmap(ID_DI);
|
|
if (tmap)
|
|
{
|
|
if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
|
|
{
|
|
texture = (BitmapTex*)tmap;
|
|
bmpList.AddBitmap(texture);
|
|
//TCHAR *temp2 = texture->GetMapName();
|
|
//DEBUG_STREAM << temp2 << " submap " << w << endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
|
|
BitmapTex *temp = NULL;
|
|
for (int z=0;z<bmpList.Count();z++)
|
|
{
|
|
temp = bmpList.GetBitmap(z);
|
|
TCHAR *temp_string = temp->GetMapName();
|
|
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//
|
|
//############################################################################
|
|
//############################## MtlKeeper #############################
|
|
//############################################################################
|
|
//
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MtlKeeper::AddMtl(Mtl* mtl)
|
|
{
|
|
if (!mtl) {
|
|
return FALSE;
|
|
}
|
|
|
|
int numMtls = mtlTab.Count();
|
|
for (int i=0; i<numMtls; i++) {
|
|
if (mtlTab[i] == mtl) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
mtlTab.Append(1, &mtl, 25);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MtlKeeper::GetMtlID(Mtl* mtl)
|
|
{
|
|
int numMtls = mtlTab.Count();
|
|
for (int i=0; i<numMtls; i++) {
|
|
if (mtlTab[i] == mtl) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MtlKeeper::Count()
|
|
{
|
|
return mtlTab.Count();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Mtl*
|
|
MtlKeeper::GetMtl(int id)
|
|
{
|
|
return mtlTab[id];
|
|
}
|
|
|
|
//
|
|
//############################################################################
|
|
//############################## BitmapKeeper #############################
|
|
//############################################################################
|
|
//
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
BitmapKeeper::AddBitmap(BitmapTex* bitmap)
|
|
{
|
|
if (!bitmap) {
|
|
return FALSE;
|
|
}
|
|
|
|
int numBitmap = bitmapTab.GetLength();
|
|
for (int i=0; i<numBitmap; i++)
|
|
{
|
|
BitmapTex *comp_bitmap = bitmapTab[i];
|
|
if (comp_bitmap == bitmap)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
bitmapTab.SetLength(numBitmap + 1);
|
|
|
|
bitmapTab[numBitmap] = bitmap;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
BitmapKeeper::GetBitmapID(BitmapTex* bitmap)
|
|
{
|
|
int numBitmap = bitmapTab.GetLength();
|
|
for (int i=0; i<numBitmap; i++) {
|
|
if (bitmapTab[i] == bitmap) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
BitmapKeeper::Count()
|
|
{
|
|
return bitmapTab.GetLength();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
BitmapTex*
|
|
BitmapKeeper::GetBitmap(int id)
|
|
{
|
|
if (bitmapTab.GetLength())
|
|
return bitmapTab[id];
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//############################################################################
|
|
//############################## NodeKeeper ###############################
|
|
//############################################################################
|
|
//
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
NodeKeeper::AddNode(INode* node)
|
|
{
|
|
if (!node) {
|
|
return FALSE;
|
|
}
|
|
|
|
int numNodes = nodeTab.Count();
|
|
for (int i=0; i<numNodes; i++) {
|
|
if (nodeTab[i] == node) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
nodeTab.Append(1, &node, 25);
|
|
return TRUE;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
NodeKeeper::GetNodeID(INode* node)
|
|
{
|
|
int numNodes = nodeTab.Count();
|
|
for (int i=0; i<numNodes; i++) {
|
|
if (nodeTab[i] == node) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
NodeKeeper::Count()
|
|
{
|
|
return nodeTab.Count();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
INode*
|
|
NodeKeeper::GetNode(int id)
|
|
{
|
|
return nodeTab[id];
|
|
}
|
|
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXScene::GetMeshProxies(INode* node, int& mesh_count)
|
|
{
|
|
for (int c = 0; c < node->NumberOfChildren(); c++) {
|
|
GetMeshProxies(node->GetChildNode(c),mesh_count);
|
|
Proxies::ChildProxy* child = CheckNodeForMesh(node->GetChildNode(c));
|
|
if (child != NULL)
|
|
{
|
|
meshProxies[mesh_count] = child;
|
|
mesh_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXScene::CheckNodeForMesh(INode *child)
|
|
{
|
|
Check_Object(this);
|
|
|
|
TCHAR *name = child->GetName();
|
|
|
|
//
|
|
//-------------------
|
|
// Get the child type
|
|
//-------------------
|
|
//
|
|
ObjectState os = child->EvalWorldState(time);
|
|
Proxies::ChildProxy *proxy = NULL;
|
|
|
|
if (os.obj)
|
|
{
|
|
if (os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID)
|
|
{
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// If the child is a mesh, we will need to auto-create a group between the
|
|
// current parent and the mesh's children if it has any
|
|
//------------------------------------------------------------------------
|
|
//
|
|
if (os.obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0)))
|
|
{
|
|
proxy = MAXPolygonMesh::MakeProxy(this, NULL, child, time, 0, 0);
|
|
Register_Object(proxy);
|
|
return proxy;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
INode *MAXScene::FindRoot(INode *node)
|
|
{
|
|
for (int c = 0; c < node->NumberOfChildren(); c++)
|
|
{
|
|
INode *result = FindRoot(node->GetChildNode(c));
|
|
if (result) return result;
|
|
INode *child = node->GetChildNode(c);
|
|
TCHAR *name = child->GetName();
|
|
if (strcmp(name,"ROOT") == 0)
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Page *MAXScene::FindHint(Stuff::MString name)
|
|
{
|
|
Stuff::MString filename = strHintFile;
|
|
Page *page = m_HintFile.FindPage(name);
|
|
Page *newpage=NULL;
|
|
if (NULL == page)
|
|
{
|
|
bool bDone = false;
|
|
newpage = m_HintFile.AddPage(name);
|
|
while (!bDone)
|
|
{
|
|
if (filename !="")
|
|
{
|
|
if (!gos_DoesFileExist(filename))
|
|
{
|
|
|
|
// Get the game dir from the plugins.ini
|
|
Stuff::MString gameDir;
|
|
|
|
TSTR ini_file = iPointer->GetDir(APP_PLUGCFG_DIR);
|
|
ini_file += "\\Plugins.ini";
|
|
|
|
Stuff::NotationFile data_file(ini_file);
|
|
|
|
const char* read_dir = NULL;
|
|
Page *ppage = data_file.FindPage("BRBData");
|
|
if (ppage)
|
|
ppage->GetEntry("GameDir", &read_dir);
|
|
if (read_dir)
|
|
gameDir = read_dir;
|
|
|
|
filename = gameDir+"\\"+filename;
|
|
|
|
}
|
|
NotationFile notefile(filename);
|
|
page = notefile.FindPage(name);
|
|
if (page)
|
|
{
|
|
Page::NoteIterator *notes = page->MakeNoteIterator();
|
|
|
|
Note *note;
|
|
while (note = notes->ReadAndNext())
|
|
{
|
|
const char *entry;
|
|
note->GetEntry(&entry);
|
|
newpage->AppendEntry(note->GetName(),entry);
|
|
page = newpage;
|
|
}
|
|
delete notes;
|
|
bDone = true;
|
|
filename="";
|
|
}
|
|
else
|
|
{
|
|
page = notefile.FindPage("");
|
|
if (page)
|
|
{
|
|
const char *entry;
|
|
if (page->GetEntry("Parent",&entry))
|
|
{
|
|
filename = entry;
|
|
}
|
|
else
|
|
{
|
|
filename="";
|
|
bDone=true;
|
|
page = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
filename="";
|
|
bDone=true;
|
|
page = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDone = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
newpage = page;
|
|
}
|
|
|
|
return newpage;
|
|
}
|