diff --git a/Engine/source/ts/tsMeshFit.cpp b/Engine/source/ts/tsMeshFit.cpp index 28ab8736a..495a469c4 100644 --- a/Engine/source/ts/tsMeshFit.cpp +++ b/Engine/source/ts/tsMeshFit.cpp @@ -1021,6 +1021,9 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char mShape->getNodeWorldTransform( nodeIndex, &mat ); if ( !mat.isIdentity() ) setNodeTransform( colNodeName, TransformF::Identity ); + + // clean node commands that are related to this target. + cleanTargetNodes(colNodeName, target); } // Add the meshes to the shape => @@ -1064,15 +1067,8 @@ DefineTSShapeConstructorMethod( addCollisionDetail, bool, ( S32 size, const char mShape->addMesh( mesh->tsmesh, meshName ); // Add a node for this object if needed (non-identity transform) - if ( mesh->transform.isIdentity() ) - { - mShape->setObjectNode( objName, colNodeName ); - } - else - { - addNode( meshName, colNodeName, TransformF( mesh->transform ) ); - mShape->setObjectNode( objName, meshName ); - } + addNode( meshName, colNodeName, target, TransformF( mesh->transform ) ); + mShape->setObjectNode( objName, meshName ); } mShape->init(); diff --git a/Engine/source/ts/tsShapeConstruct.cpp b/Engine/source/ts/tsShapeConstruct.cpp index 74582cefd..3031ec110 100644 --- a/Engine/source/ts/tsShapeConstruct.cpp +++ b/Engine/source/ts/tsShapeConstruct.cpp @@ -1111,8 +1111,8 @@ DefineTSShapeConstructorMethod(renameNode, bool, (const char* oldName, const cha return true; }} -DefineTSShapeConstructorMethod(addNode, bool, (const char* name, const char* parentName, TransformF txfm, bool isWorld), (TransformF::Identity, false), - (name, parentName, txfm, isWorld), false, +DefineTSShapeConstructorMethod(addNode, bool, (const char* name, const char* parentName, const char* target, TransformF txfm, bool isWorld), (TransformF::Identity, false), + (name, parentName, target, txfm, isWorld), false, "Add a new node.\n" "@param name name for the new node (must not already exist)\n" "@param parentName name of an existing node to be the parent of the new node. " @@ -2433,6 +2433,7 @@ void TSShapeConstructor::ChangeSet::add( TSShapeConstructor::ChangeSet::Command& // Detail level commands case CmdRenameDetailLevel: addCommand = addCmd_renameDetailLevel(cmd); break; case CmdRemoveDetailLevel: addCommand = addCmd_removeDetailLevel(cmd); break; + case CmdAddCollisionDetail: addCommand = addCmd_addDetailLevel(cmd); break; case CmdSetDetailLevelSize: addCommand = addCmd_setDetailSize(cmd); break; case CmdAddImposter: addCommand = addCmd_addImposter(cmd); break; case CmdRemoveImposter: addCommand = addCmd_removeImposter(cmd); break; @@ -3302,6 +3303,28 @@ bool TSShapeConstructor::ChangeSet::addCmd_renameDetailLevel(const TSShapeConstr return true; } +bool TSShapeConstructor::ChangeSet::addCmd_addDetailLevel(const TSShapeConstructor::ChangeSet::Command& newCmd) +{ + const char* targ = newCmd.argv[2]; + for (S32 index = mCommands.size() - 1; index >= 0; index--) + { + Command& cmd = mCommands[index]; + switch (cmd.type) + { + case CmdAddCollisionDetail: + if (!dStricmp(targ, cmd.argv[2])) + { + mCommands.erase(index); + } + break; + default: + break; + } + } + + return true; +} + bool TSShapeConstructor::ChangeSet::addCmd_removeDetailLevel(const TSShapeConstructor::ChangeSet::Command& newCmd) { // Remove any previous command that references the detail, but stop if a mesh @@ -3480,3 +3503,32 @@ void TSShapeConstructor::onActionPerformed() } } } + +void TSShapeConstructor::cleanTargetNodes(const char* detail, const char* target) +{ + for (S32 index = mChangeSet.mCommands.size() - 1; index >= 0; index--) + { + ChangeSet::Command& cmd = mChangeSet.mCommands[index]; + switch (cmd.type) + { + case ChangeSet::eCommandType::CmdAddNode: + // node name starts with col + if (dStrStartsWith(cmd.argv[0], "Col")) + { + // node has the same detail and same target + if (!dStricmp(detail, cmd.argv[1]) && !dStricmp(target, cmd.argv[2])) + { + // now remove it from shape + mShape->removeMesh(cmd.argv[0]); + mShape->removeNode(cmd.argv[0]); + + // erase the command + mChangeSet.mCommands.erase(index); + } + } + break; + default: + break; + } + } +} diff --git a/Engine/source/ts/tsShapeConstruct.h b/Engine/source/ts/tsShapeConstruct.h index 98220d880..7cbbc0a49 100644 --- a/Engine/source/ts/tsShapeConstruct.h +++ b/Engine/source/ts/tsShapeConstruct.h @@ -142,6 +142,7 @@ public: bool addCmd_setBounds(const Command& newCmd); bool addCmd_renameDetailLevel(const Command& newCmd); + bool addCmd_addDetailLevel(const Command& newCmd); bool addCmd_removeDetailLevel(const Command& newCmd); bool addCmd_setDetailSize(const Command& newCmd); bool addCmd_addImposter(const Command& newCmd); @@ -253,6 +254,7 @@ public: /// @name Nodes ///@{ + void cleanTargetNodes(const char* detail, const char* target); S32 getNodeCount(); S32 getNodeIndex(const char* name); const char* getNodeName(S32 index); @@ -265,7 +267,7 @@ public: TransformF getNodeTransform(const char* name, bool isWorld = false); bool setNodeTransform(const char* name, TransformF txfm, bool isWorld = false); bool renameNode(const char* oldName, const char* newName); - bool addNode(const char* name, const char* parentName, TransformF txfm = TransformF::Identity, bool isWorld = false); + bool addNode(const char* name, const char* parentName, const char* target = "", TransformF txfm = TransformF::Identity, bool isWorld = false); bool removeNode(const char* name); ///@} diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript index a82e9ea40..94a06ad95 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.tscript @@ -1091,36 +1091,15 @@ function ActionEditCollision::updateCollision( %this, %type, %target, %fillMode, if ( %index != -1 ) %colNode = ShapeEditor.shape.getNodeName( %index ); - if(%target $= %oldTarget) - { - // First remove the old detail and collision nodes - %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); - %meshCount = getFieldCount( %meshList ); - if ( %meshCount > 0 ) - { - ShapeEditor.shape.removeDetailLevel( %colDetailSize ); - for ( %i = 0; %i < %meshCount; %i++ ) - ShapeEdPropWindow.update_onMeshRemoved( getField( %meshList, %i ) ); - } - - %nodeList = ShapeEditor.getNodeNames( %colNode, "" ); - %nodeCount = getFieldCount( %nodeList ); - if ( %nodeCount > 0 ) - { - for ( %i = 0; %i < %nodeCount; %i++ ) - ShapeEditor.shape.removeNode( getField( %nodeList, %i ) ); - ShapeEdPropWindow.update_onNodeRemoved( %nodeList, %nodeCount ); - } - } // Add the new node and geometry if ( %type $= "" ) return; - + if ( !ShapeEditor.shape.addCollisionDetail( %colDetailSize, %type, %target, %fillMode, %depth, %merge, %concavity, %maxVerts, %boxMax, %sphereMax, %capsuleMax ) ) return false; - + // Update UI %meshList = ShapeEditor.getDetailMeshList( %colDetailSize ); ShapeEdPropWindow.update_onNodeAdded( %colNode, ShapeEditor.shape.getNodeCount() ); // will also add child nodes