#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; }