/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "HeadSpin.h" #include "max.h" #include "plResetXform.h" #include "../MaxMain/plMaxNode.h" #include "../MaxComponent/plComponent.h" void plResetXform::ResetSelected() const { ResetSelectedRecur(GetCOREInterface()->GetRootNode()); } void plResetXform::ResetSelectedRecur(INode* node) const { if( !node ) return; if( node->Selected() ) { IResetNode(node); } int i; for( i = 0; i < node->NumberOfChildren(); i++ ) ResetSelectedRecur(node->GetChildNode(i)); } void plResetXform::IResetNode(INode* node) const { const char* dbgNodeName = node->GetName(); BOOL deleteIt = false; TriObject* oldObj = IGetTriObject(node, deleteIt); if( !oldObj ) return; Mesh& oldMesh = oldObj->mesh; TimeValue t(0); Matrix3 nodeTM = node->GetNodeTM(t); Matrix3 objectTM = node->GetObjectTM(t); Matrix3 otm = objectTM * Inverse(nodeTM); Point3 u = nodeTM.GetRow(0); Point3 v = nodeTM.GetRow(1); Point3 w = CrossProd(u, v); v = CrossProd(w, u); u = Normalize(u); v = Normalize(v); w = Normalize(w); Matrix3 newXform(u, v, w, nodeTM.GetTrans()); Matrix3 vtxXform = otm * nodeTM * Inverse(newXform) * Inverse(otm); TriObject* newObj = CreateNewTriObject(); Mesh& newMesh = newObj->mesh; newMesh = oldMesh; int i; for( i = 0; i < newMesh.getNumVerts(); i++ ) { Point3 p = vtxXform * newMesh.getVert(i); newMesh.getVert(i) = p; } if( nodeTM.Parity() ) { for( i = 0; i < newMesh.getNumFaces(); i++ ) { newMesh.FlipNormal(i); } } node->SetObjectRef(newObj); node->SetNodeTM(t, newXform); if( deleteIt ) oldObj->DeleteThis(); } TriObject* plResetXform::IGetTriObject(INode* node, BOOL& deleteIt) const { Object *obj = node->EvalWorldState(TimeValue(0)).obj; if( !obj ) return NULL; if( !obj->CanConvertToType( triObjectClassID ) ) return NULL; // Convert to triMesh object TriObject *meshObj = (TriObject*)obj->ConvertToType(TimeValue(0), triObjectClassID); if( !meshObj ) return NULL; deleteIt = meshObj != obj; return meshObj; } void plSelectNonRenderables::ICollectNonDrawablesRecur(plMaxNode* node, INodeTab& nodeTab) const { plComponentBase* comp = node->ConvertToComponent(); if( comp ) comp->CollectNonDrawables(nodeTab); int i; for( i = 0; i < node->NumberOfChildren(); i++ ) ICollectNonDrawablesRecur((plMaxNode*)node->GetChildNode(i), nodeTab); } void plSelectNonRenderables::SelectNonRenderables() const { INodeTab nodeTab; ICollectNonDrawablesRecur((plMaxNode*)GetCOREInterface()->GetRootNode(), nodeTab); INodeTab unhidden; int i; for( i = 0; i < nodeTab.Count(); i++ ) { INode* node = nodeTab[i]; if( !node->IsHidden() ) unhidden.Append(1, &node); } theHold.Begin(); TSTR undostr; undostr.printf("SelNonRend"); GetCOREInterface()->SelectNodeTab(unhidden, true, true); theHold.Accept(undostr); }