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.
522 lines
11 KiB
C++
522 lines
11 KiB
C++
#include "MAXProxyHeaders.hpp"
|
|
|
|
//
|
|
//############################################################################
|
|
//############################ MAXLight #############################
|
|
//############################################################################
|
|
//
|
|
|
|
MemoryBlock*
|
|
MAXLight::AllocatedMemory = NULL;
|
|
MAXLight::ClassData*
|
|
MAXLight::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::InitializeClass()
|
|
{
|
|
Verify(!AllocatedMemory);
|
|
AllocatedMemory =
|
|
new MemoryBlock(
|
|
sizeof(MAXLight),
|
|
10,
|
|
10,
|
|
"MAXLight"
|
|
);
|
|
Register_Object(AllocatedMemory);
|
|
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
MAXLightClassID,
|
|
"MAXLight",
|
|
LightProxy::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
|
|
Unregister_Object(AllocatedMemory);
|
|
delete AllocatedMemory;
|
|
AllocatedMemory = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::Destroy()
|
|
{
|
|
Check_Object(this);
|
|
Verify(referenceCount == 1);
|
|
STOP(("Not implemented"));
|
|
DetachReference();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MAXLight::MAXLight(
|
|
MAXScene *scene,
|
|
MAXGroup *parent,
|
|
INode *light,
|
|
int index
|
|
):
|
|
Proxies::LightProxy(DefaultData, scene, parent),
|
|
proxiedLight(light),
|
|
childIndex(index)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(scene);
|
|
Check_Pointer(light);
|
|
Check_Object(this);
|
|
|
|
lightObject = NULL;
|
|
TimeValue time = scene->GetTime();
|
|
Object *obj = light->EvalWorldState(time).obj;
|
|
if (obj->SuperClassID()==LIGHT_CLASS_ID)
|
|
{
|
|
lightObject = (LightObject *)obj->ConvertToType(time,
|
|
Class_ID(LIGHT_CLASS_ID, 0));
|
|
lightObject = (LightObject *)obj;
|
|
Interval valid;
|
|
lightObject->EvalLightState(0,valid, &lightState);
|
|
}
|
|
if (obj->CanConvertToType(Class_ID(TARGET_CLASS_ID, 0)))
|
|
{
|
|
// This is the a light target for directional lights, From Solution 1888
|
|
// The directional light looks down its negative Z axis (just like a camera does). You'll have to get the NodeTM of the light using GetNodeTMAfterWSM(), since the TM can be affected by a SpaceWarp and you need to take that into account.
|
|
}
|
|
//Verify(lightObject != NULL);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MAXLight::~MAXLight()
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
Check_Pointer(proxiedLight);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::TransferAndAppendToParentGroup(Proxies::GroupProxy *parent)
|
|
{
|
|
Check_Object(this);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXLight::UseNextSiblingProxy()
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(proxiedLight);
|
|
INode *parent = proxiedLight->GetParentNode();
|
|
Check_Pointer(parent);
|
|
|
|
unsigned children = parent->NumberOfChildren();;
|
|
INode *next = NULL;
|
|
|
|
if (!children)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (childIndex+1 < children)
|
|
{
|
|
next = parent->GetChildNode(childIndex+1);
|
|
}
|
|
if (next)
|
|
{
|
|
return
|
|
GetSceneProxy()->InterpretRecord(GetParentGroupProxy(), next, childIndex+1,true);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Proxies::ChildProxy*
|
|
MAXLight::UsePreviousSiblingProxy()
|
|
{
|
|
|
|
Check_Object(this);
|
|
Check_Pointer(proxiedLight);
|
|
INode *parent = proxiedLight->GetParentNode();
|
|
Check_Pointer(parent);
|
|
|
|
unsigned children = parent->NumberOfChildren();;
|
|
INode *prev = NULL;
|
|
|
|
if (!children)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (childIndex-1 >= 0)
|
|
{
|
|
prev = parent->GetChildNode(childIndex+1);
|
|
}
|
|
if (prev)
|
|
{
|
|
return
|
|
GetSceneProxy()->InterpretRecord(GetParentGroupProxy(), prev, childIndex-1,true);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetName(MString *name)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(name);
|
|
Check_Pointer(proxiedLight);
|
|
|
|
TCHAR *string = proxiedLight->GetName();
|
|
int len = strlen(string);
|
|
if (len != 0)
|
|
{
|
|
*name = string;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetName(const char* name)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(name);
|
|
Check_Pointer(proxiedLight);
|
|
|
|
TCHAR *string = (TCHAR *)name;
|
|
proxiedLight->SetName(string);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetLocalToParent(LinearMatrix4D *matrix)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(matrix);
|
|
Check_Pointer(proxiedLight);
|
|
|
|
#if 1
|
|
|
|
Matrix3 parentTM, nodeTM, localTM;
|
|
nodeTM = proxiedLight->GetNodeTM(0);
|
|
parentTM = proxiedLight->GetParentTM(0);
|
|
localTM = nodeTM*Inverse(parentTM);
|
|
//Matrix3 parentTM = proxiedLight->GetNodeTM(GetSceneProxy()->GetTime(),NULL);
|
|
//Matrix3 myTM = proxiedLight->GetParentTM(GetSceneProxy()->GetTime());
|
|
//Matrix3 mat = Inverse(parentTM) * myTM;
|
|
|
|
#else
|
|
|
|
Matrix3 parentTM = proxiedLight->GetObjTMAfterWSM(GetSceneProxy()->GetTime(),NULL);
|
|
Matrix3 myTM = proxiedLight->GetObjTMAfterWSM(GetSceneProxy()->GetTime(), NULL);
|
|
|
|
Matrix3 mat = Inverse(parentTM) * myTM;
|
|
|
|
#endif
|
|
|
|
AffineParts parts;
|
|
decomp_affine(localTM, &parts);
|
|
|
|
Point3D translation;
|
|
translation=ConvertMaxToMW(parts.t);
|
|
|
|
UnitQuaternion rotation;
|
|
rotation=ConvertMaxToMW(parts.q);
|
|
|
|
|
|
matrix->BuildRotation(rotation);
|
|
matrix->BuildTranslation(translation);
|
|
return *matrix != LinearMatrix4D::Identity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetLocalToParent(const LinearMatrix4D &matrix)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&matrix);
|
|
// Matrix3 *mat3 = matrix;
|
|
// SetNodeTM(time, mat3);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetOBB(OBB *obb)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(obb);
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetOBB(const OBB &obb)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&obb);
|
|
STOP(("Not Possible"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetBoundingSphere(Sphere *sphere)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(sphere);
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetBoundingSphere(const Sphere &sphere)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&sphere);
|
|
STOP(("Not Possible"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::GetColor(RGBColor *color)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(color);
|
|
if (lightObject)
|
|
{
|
|
Check_Pointer(lightObject);
|
|
|
|
//
|
|
//--------------------
|
|
// Get the light color
|
|
//--------------------
|
|
//
|
|
color->red = lightState.color.r;
|
|
color->green = lightState.color.g;
|
|
color->blue = lightState.color.b;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetColor(const RGBColor &color)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&color);
|
|
Check_Pointer(lightObject);
|
|
//
|
|
//--------------------
|
|
// Set the light color
|
|
//--------------------
|
|
//
|
|
//lightData->color.x = color.red;
|
|
//lightData->color.y = color.green;
|
|
//lightData->color.z = color.blue;
|
|
Point3 c(color.red,color.green,color.blue);
|
|
lightObject->SetRGBColor(0,c);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::IsAmbient()
|
|
{
|
|
Check_Object(this);
|
|
//Check_Pointer(lightData);
|
|
if (lightObject)
|
|
{
|
|
if (lightState.type == AMBIENT_LGT)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetAmbient(bool ambient)
|
|
{
|
|
Check_Object(this);
|
|
STOP(("Not implemented"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetFalloffDistance(
|
|
Scalar *n,
|
|
Scalar *f
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(n);
|
|
Check_Pointer(f);
|
|
|
|
//
|
|
// this routine seems to ask for the fall off distance but
|
|
// JM's version returns the start of the fall off and the
|
|
// end of the fall off I think! So I will check the type of light
|
|
// to see if it can have falloff, get the fall off angle. If
|
|
// the falloff angle is not equal 0.0 I set the start to 0 and
|
|
// get the fall off distance and set that as the end
|
|
//
|
|
if (!lightObject)
|
|
return false;
|
|
if (lightState.type == OMNI_LGT || lightState.type == SPOT_LGT
|
|
|| lightState.type == DIRECT_LGT)
|
|
{
|
|
Interval valid(0,0);
|
|
|
|
float falloff_angle =
|
|
lightObject->GetFallsize(GetSceneProxy()->GetTime(),valid);
|
|
if (falloff_angle != 0.0)
|
|
{
|
|
*n = 0.0;
|
|
*f = lightObject->GetTDist(GetSceneProxy()->GetTime(),valid);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
*n = 0.0;
|
|
*f = 0.0;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetFalloffDistance(
|
|
Scalar n,
|
|
Scalar f
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(lightObject);
|
|
Scalar distance = f - n;
|
|
lightObject->SetTDist(GetSceneProxy()->GetTime(),(float)distance);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MAXLight::GetSpreadAngle(Radian *angle)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(angle);
|
|
if (lightObject)
|
|
{
|
|
Check_Pointer(lightObject);
|
|
|
|
MAXScene *scene = GetSceneProxy();
|
|
Check_Pointer(scene);
|
|
|
|
if (lightState.type != SPOT_LGT)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Interval valid = Interval(0,0);
|
|
angle->angle = lightObject->GetFallsize(scene->GetTime(), valid);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MAXLight::SetSpreadAngle(const Radian &radian)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(lightObject);
|
|
|
|
MAXScene *scene = GetSceneProxy();
|
|
Check_Pointer(scene);
|
|
lightObject->SetFallsize(scene->GetTime(),radian.angle);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
INode
|
|
*MAXLight::GetNextChild()
|
|
{
|
|
Check_Pointer(proxiedLight);
|
|
INode *parent = proxiedLight->GetParentNode();
|
|
Check_Pointer(parent);
|
|
unsigned children = parent->NumberOfChildren();;
|
|
|
|
if (!children)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (childIndex < children)
|
|
{
|
|
INode *child = parent->GetChildNode(childIndex);
|
|
childIndex++;
|
|
return child;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
INode
|
|
*MAXLight::GetPreviousChild()
|
|
{
|
|
Check_Pointer(proxiedLight);
|
|
INode *parent = proxiedLight->GetParentNode();
|
|
Check_Pointer(parent);
|
|
unsigned children = parent->NumberOfChildren();;
|
|
|
|
if (!children)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (childIndex > -1)
|
|
{
|
|
INode *child = parent->GetChildNode(childIndex);
|
|
childIndex--;
|
|
return child;
|
|
}
|
|
return NULL;
|
|
}
|