void AddSceneLights(SContext* sc, MtlBaseLib* mtls) { INode* scene = GetCOREInterface()->GetRootNode(); for (int i=0; i<scene->NumberOfChildren(); i++) { sceneLightEnum(scene->GetChildNode(i), sc, mtls); } }
BOOL PFOperatorInstanceShapeMXSValidator::Validate(PB2Value& v) { INode* iNode = (INode*)v.r; if (iNode == NULL) return NULL; TimeValue t = GetCOREInterface()->GetTime(); Tab<INode*> stack; stack.Append(1, &iNode, 10); while (stack.Count()) { INode *node = stack[stack.Count()-1]; stack.Delete(stack.Count()-1, 1); Object *obj = node->EvalWorldState(t).obj; if (obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) return TRUE; // add children to the stack for (int i = 0; i < node->NumberOfChildren(); i++) { INode *childNode = node->GetChildNode(i); if (childNode) stack.Append(1, &childNode, 10); } } return FALSE; }
void MembraneVertexShader::GetCameraPosition(Point3 &Pos) { Interface *ip = GetCOREInterface(); INode *pObj; Matrix3 objTM; Pos.x = 0.0f; Pos.y = 0.0f; Pos.z = -200.0f; INode *pRoot =ip->GetRootNode(); int numNodes = pRoot->NumberOfChildren(); for( int ctr = 0; ctr < numNodes; ctr++) { pObj = pRoot->GetChildNode(ctr); // The ObjectState is a 'thing' that flows down the pipeline containing // all information about the object. By calling EvalWorldState() we tell // max to eveluate the object at end of the pipeline. ObjectState os = pObj->EvalWorldState(ip->GetTime()); // The obj member of ObjectState is the actual object we will export. if (os.obj) { // We look at the super class ID to determine the type of the object. switch(os.obj->SuperClassID()) { case CAMERA_CLASS_ID: objTM = pObj->GetNodeTM(ip->GetTime()); Pos = objTM.GetTrans(); break; } } } }
static void GetSceneLights(Tab<INode*> & lights) { Interface *ip = GetCOREInterface(); TimeValue t = ip->GetTime(); INode * Root = ip->GetRootNode(); int Count = Root->NumberOfChildren(); int i=0; for( i=0; i < Count; i++) { INode * node = Root->GetChildNode(i); ObjectState Os = node->EvalWorldState(t); if(Os.obj && Os.obj->SuperClassID() == LIGHT_CLASS_ID) { lights.Append(1, &node); } } }
int Blockporter::DoExport(const TCHAR* name, ExpInterface* ei, Interface* i, BOOL supressPrompts, DWORD options) { INode* root; //caption and message for MessagesBoxes TCHAR msg[MB_BUFFER_LENGTH]; TCHAR cap[MB_BUFFER_LENGTH]; //Get the root node root = i->GetRootNode(); //the node of our object should be a groupnode, which contains every object //we want to export i->PushPrompt(_T("Searching for Group...")); bool found = false; for(int idx = 0; idx < root->NumberOfChildren(); idx++) { if(root->GetChildNode(idx)->IsGroupHead()) { //we found our group //next step is to make the group node our new root, because every object //we want is part of this group found = true; root = root->GetChildNode(idx); break; } } if(!found) { MessageBox(nullptr, GetString(IDS_ERROR_NO_GROUP, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR); return 0; } //Now that we have the groupnode let's compare the fileversions if(!IsNewModelVersion(name, root->GetName())) { if(MessageBox(nullptr, GetString(IDS_VER_TO_LOW_MSG, msg), GetString(IDS_VER_TO_LOW_CAP, cap), MB_YESNO | MB_ICONEXCLAMATION) == IDNO) return 1; } i->PushPrompt(_T("Opening File")); Interface14* iface = GetCOREInterface14(); UINT code = iface->DefaultTextSaveCodePage(true); MaxSDK::Util::Path storageNamePath(name); storageNamePath.SaveBaseFile(); switch (code & MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_MASK) { case CP_UTF8: mStream = _tfopen(name, _T("wt, ccs=UFT-8")); break; case MaxSDK::Util::MaxStringDataEncoding::MSDE_CP_UTF16: mStream = _tfopen(name, _T("wt, ccs=UTF-16BE")); break; default: mStream = _tfopen(name, _T("wt")); } if(!mStream) return 0; //now we have our file stream, so let's write the header i->PushPrompt(_T("Writing Header")); WriteHeader(root->GetName(), root->NumberOfChildren()); //now that we have the header written, let's iterate through the objects in the //group and export the meshes and lights INode* child; Point3 pMin(0,0,0), pMax(0,0,0); for(int idx = 0; idx < root->NumberOfChildren(); idx++) { child = root->GetChildNode(idx); i->PushPrompt(_T("Processing Object %s", child->GetName())); if(child->IsGroupHead()) { MessageBox(nullptr, GetString(IDS_ERROR_TO_MANY_GROUPS, msg), GetString(IDS_GENERAL_ERROR, cap), MB_OK | MB_ICONERROR); continue; } ObjectState os = child->EvalWorldState(0); //let's take a look at the SuperClassID of the object //so we find out if it's a mesh or a light if(!os.obj) continue; //somehow this node doesn't have an object Box3 boundBox; switch(os.obj->SuperClassID()) { case GEOMOBJECT_CLASS_ID: _ftprintf(mStream, _T("<ObjectID=%i>\n"), idx); i->PushPrompt(_T("Writing MeshData for Object %s", child->GetName())); boundBox = WriteMeshData(child, idx); pMin.x = (boundBox.Min().x < pMin.x) ? boundBox.Min().x : pMin.x; pMin.y = (boundBox.Min().y < pMin.y) ? boundBox.Min().y : pMin.y; pMax.x = (boundBox.Max().x > pMax.x) ? boundBox.Max().x : pMax.x; pMax.y = (boundBox.Max().y > pMax.y) ? boundBox.Max().y : pMax.y; i->PushPrompt(_T("Writing MaterialData for Object %s", child->GetName())); WriteMaterialData(child); _ftprintf(mStream, _T("</Object>\n")); break; //case LIGHT_CLASS_ID: // WriteLightData(child, idx); // break; } } //Write the Bounding Box _ftprintf(mStream, _T("<BoundingBox>\n")); _ftprintf(mStream, _T("\t<Min=%f,%f>\n"), pMin.x, pMin.y); _ftprintf(mStream, _T("\t<Max=%f,%f>\n"), pMax.x, pMax.y); _ftprintf(mStream, _T("</BoundingBox>\n")); //we are done exporting, so close the stream i->PushPrompt(_T("Closing file...")); fclose(mStream); MessageBox(nullptr, GetString(IDS_FINISH_MSG, msg), GetString(IDS_FINISH_CAP, cap), MB_OK | MB_ICONINFORMATION); return 1; }
void Lighting::GetLightsFromScene() { Interface *Ip; // INode *Node,*Root; Matrix3 Mat; int i,Count; ObjectState Os; // LightObject *LightObj; // LightState Ls; // RenderLight Light; TimeValue Time; Interval valid; // Point3 Pos,Target; Ip = GetCOREInterface(); Time = Ip->GetTime(); INode * Root = Ip->GetRootNode(); Count = Root->NumberOfChildren(); sceneLights.SetCount(0); for(i=0; i < Count; i++) { INode * Node = Root->GetChildNode(i); Os = Node->EvalWorldState(Time); if(Os.obj && Os.obj->SuperClassID() == LIGHT_CLASS_ID) { sceneLights.Append(1,&Node); /* LightObj = (LightObject *)Os.obj; LightObj->EvalLightState(Time,valid,&Ls); Mat = Node->GetNodeTM(Time); Pos = Mat.GetTrans(); Light.m_Angle = Ls.hotsize; if(Light.m_Angle < 2.0f) { Light.m_Angle = 2.0f; } Mat = Node->GetNodeTM(Time); Light.m_Dir = Mat.GetRow(2); Light.m_Type = (RenderLightType)Ls.type; Light.m_Pos = Pos; Light.m_Dir = Light.m_Dir.Normalize(); Light.m_Color = Ls.color * Ls.intens; if(Ls.useAtten) { Light.m_Atten = true; if(Ls.attenStart <= 0.0f) { Light.m_InnerRange = 1.0f; } else { Light.m_InnerRange = 1.0f / (Ls.attenStart * 2.0f); } if(Ls.attenEnd <= 0.0f) { Light.m_OuterRange = 0.0f; } else { Light.m_OuterRange = 1.0f / (Ls.attenEnd * 2.0f); } } else { Light.m_Atten = false; Light.m_InnerRange = 0.1f; Light.m_OuterRange = 0.00001f; } m_Lights.push_back(Light); */ } } m_forceUpdate = false; }
NxActor* MxActor::createNxActor() { if (m_bulletBody) { MaxMsgBox(NULL, _T("Error: body was already added to the dynamics world"), _T("Error"), MB_OK); return 0; } // find proxy node m_proxyNode = NULL; TSTR str = MxUserPropUtils::GetUserPropStr(m_node, "Proxy_Geometry"); char* proxyName = str.data(); if(proxyName && strlen(proxyName) > 0 && (stricmp(proxyName, "<None>") != 0)) { m_proxyNode = GetCOREInterface()->GetINodeByName(proxyName); } // ccMaxNode* pActorNode = ccMaxWorld::FindNode(m_node); assert(pActorNode); maxNodeActor = pActorNode; maxNodeProxy = NULL; if(m_proxyNode) { maxNodeProxy = ccMaxWorld::FindNode(m_proxyNode); assert(maxNodeProxy); //Point3 p1 = maxNodeActor->PhysicsNodePoseTM.GetRow(3), p2 = maxNodeProxy->PhysicsNodePoseTM.GetRow(3); Point3 p1 = maxNodeActor->NodePosInPhysics, p2 = maxNodeProxy->NodePosInPhysics; ProxyDistance = p1 - p2; } NxActorDesc& actorDesc = m_desc; NxBodyDesc& bodyDesc = m_bodyDesc; //LoadParameters(actorDesc, bodyDesc); actorDesc.globalPose = pActorNode->PhysicsNodePoseTM;//MxMathUtils::MaxMatrixToNx(pActorNode->PhysicsNodePoseTM); SaveLastPose(pActorNode->PhysicsNodePoseTM); //m_bodydesc.solverIterationCount = (NxU32)mSetting_solveriterationcount; // support it in future? std::vector<INode*> stack; std::vector<INode*> shapes; //Check if the object is using a proxy, in that case only those shapes should be added INode* current = m_node; if(m_proxyNode) current = m_proxyNode; stack.push_back(current); //DEBUG_S("List collision shapes"); while (stack.size() > 0) { current = stack[0]; if(stack.size() > 1) { stack[0] = stack.back(); } stack.pop_back(); if(current->EvalWorldState(0).obj->SuperClassID()==GEOMOBJECT_CLASS_ID) { shapes.push_back(current); } //go through grouped objects for(int i = 0; i < current->NumberOfChildren(); i++) { INode *c = current->GetChildNode(i); if (c->IsGroupMember()) { stack.push_back(c); } } } if (shapes.size() == 0) { if (gCurrentstream) gCurrentstream->printf("Unable to add %s as an actor, it has no shapes.\n", m_node->GetName()); return 0; } ccMaxNode* baseNode = pActorNode; if(maxNodeProxy) { baseNode = maxNodeProxy; } btAlignedObjectArray<btCollisionShape*> collisionShapes; btAlignedObjectArray<btTransform> localTransforms; for (int i = 0; i < shapes.size(); i++) { INode* current = shapes[i]; //DEBUG_F(" Debug adding shape node: %s\n", current->GetName()); ccMaxNode* pn = ccMaxWorld::FindNode(current); assert(pn); btCollisionShape* collisionShape = createShape(actorDesc, pn, pActorNode); collisionShapes.push_back(collisionShape); btTransform localTrans; max2Bullet(actorDesc.localPose,localTrans); localTransforms.push_back(localTrans); } //create a rigid body and add it to the world if (collisionShapes.size()) { btCollisionShape* collisionShape = 0; if (collisionShapes.size()==1) { collisionShape = collisionShapes[0]; } else { btCompoundShape* compound = new btCompoundShape(); for (int i=0;i<collisionShapes.size();i++) { compound->addChildShape(localTransforms[i],collisionShapes[i]); } //clear local pose actorDesc.localPose.IdentityMatrix(); collisionShape = compound; } if (collisionShape) { btVector3 localInertia(0,0,0); if (actorDesc.mass) { collisionShape->calculateLocalInertia(actorDesc.mass,localInertia); } m_bulletBody = new btRigidBody(actorDesc.mass,0,collisionShape,localInertia); m_bulletBody->setUserPointer(this); btScalar restitution; if (MxUserPropUtils::GetUserPropFloat(m_node, "Restitution", restitution)) { m_bulletBody->setRestitution(restitution); } btScalar staticFriction = 0.f; //take the maximum for now MxUserPropUtils::GetUserPropFloat(m_node, "StaticFriction", staticFriction); btScalar friction = 0.f; if (MxUserPropUtils::GetUserPropFloat(m_node, "Friction", friction)) { if (staticFriction>friction) friction = staticFriction; m_bulletBody->setFriction(friction); } // char bla[1024]; // sprintf(bla,"restitution=%f",restitution); // MaxMsgBox(NULL, _T(bla), _T("Error"), MB_OK); syncGlobalPose(); gDynamicsWorld->addRigidBody(m_bulletBody); // MaxMsgBox(NULL, _T("adding rigid body"), _T("Error"), MB_OK); } } bool isvalid = actorDesc.isValid(); actorDesc.name = m_node->GetName(); //NxMat34 pose0 = actorDesc.globalPose; //m_actor = gPluginData->getScene()->createActor(actorDesc); //if(! m_actor) return 0; //NxMat34 pose1 = m_actor->getGlobalPose(); // sometimes pose1 != pose0; it is strange //m_actor->userData = this; if(MxUserPropUtils::GetUserPropBool(m_node, "PutToSleep", false)) { //m_actor->putToSleep(); } // for collision force when contact happens /* NxU32 num = m_actor->getNbShapes(); NxShape*const* ps = m_actor->getShapes(); for(NxU32 i = 0; i < num; ++i) { NxShape* nxShape = ps[i]; nxShape->setFlag(NX_SF_POINT_CONTACT_FORCE, true); } */ //save last pose Matrix3 poseTM = maxNodeActor->GetCurrentTM(); SaveLastPose(poseTM); //return m_actor; return 0; }
void CExportNel::buildSkeleton (std::vector<CBoneBase>& bonesArray, INode& node, mapBoneBindPos* mapBindPos, TInodePtrInt& mapId, std::set<std::string> &nameSet, TimeValue time, sint32& idCount, sint32 father) { // **** Save the current the id int id=idCount; // **** Create a bone CBoneBase bone; // ** Set Name and id // Bone name bone.Name=getName (node); // Inserted ? if (!nameSet.insert (bone.Name).second) bone.Name+="_Second"; // Id of the father bone.FatherId=father; // Insert id with name mapId.insert (TInodePtrInt::value_type(&node, id)); // ** Set inherit flags // Must remove Scale from my father?? bone.UnheritScale= getNELUnHeritFatherScale(node); // **** Set default tracks // Get the Nel Local TM NLMISC::CVector nelScale; NLMISC::CQuat nelRot; NLMISC::CVector nelPos; getNELBoneLocalTM(node, time, nelScale, nelRot, nelPos); // Root must be exported with Identity because path are setuped interactively in the root of the skeleton if(id==0) { // Keep only the scale, because this last is not animated. nelPos= CVector::Null; nelRot= CQuat::Identity; } // Set the default tracks bone.DefaultScale=nelScale; bone.DefaultRotQuat=nelRot; bone.DefaultRotEuler=CVector (0,0,0); bone.DefaultPos=nelPos; // **** Get node bindpos matrix Matrix3 worldTM; bool matrixComputed=false; if (mapBindPos) { // Look for an entry in the map mapBoneBindPos::iterator bindPos=mapBindPos->find (&node); // Found ? if (bindPos!=mapBindPos->end()) { // Get bind pos worldTM=bindPos->second; // Computed matrixComputed=true; } } // Compute the matrix the normal way ? if (!matrixComputed) { // if we have a reference node, ie the one with the good original pos/rot/scale used for bindPos, must use it. INode *referenceNode= getNELScaleReferenceNode(node); if (referenceNode) { worldTM= referenceNode->GetNodeTM (time); } // else use mine. else { worldTM= node.GetNodeTM (time); } } // Set the bind pos of the bone, it is invNodeTM; convertMatrix (bone.InvBindPos, worldTM); bone.InvBindPos.invert(); // **** Get bone Lod disactivation bone.LodDisableDistance= getScriptAppData (&node, NEL3D_APPDATA_BONE_LOD_DISTANCE, 0.f); bone.LodDisableDistance= std::max(0.f, bone.LodDisableDistance); // **** Add the bone bonesArray.push_back (bone); // **** Call on child for (int children=0; children<node.NumberOfChildren(); children++) buildSkeleton (bonesArray, *node.GetChildNode(children), mapBindPos, mapId, nameSet, time, ++idCount, id); }