Procházet zdrojové kódy

Fixed potential infinite loop when setting morphs.
Added script API function to query morph names.
Unified AssetImporter & OgreImporter command line options regarding animations.

Lasse Öörni před 13 roky
rodič
revize
38fd976aa9

+ 8 - 8
Docs/Reference.dox

@@ -1318,8 +1318,8 @@ Usage:
 AssetImporter <command> <input file> <output file> [options]
 
 Commands:
-model Export a model
-scene Export a scene
+model Output a model
+scene Output a scene
 dump  Dump scene node structure. No output file is generated
 lod   Combine several Urho3D models as LOD levels of the output model
       Syntax: lod <dist0> <mdl0> <dist1 <mdl1> ... <output file>
@@ -1328,8 +1328,8 @@ Options:
 -b    Save scene in binary format, default format is XML
 -i    Use local ID's for scene nodes
 -mX   Output a material list file X (model mode only)
--na   Do not export animations
--nm   Do not export materials
+-na   Do not output animations
+-nm   Do not output materials
 -ns   Do not create subdirectories for resources
 -nz   Do not create a zone and a directional light (scene mode only)
 -pX   Set path X for scene resources. Default is output file path
@@ -1347,14 +1347,14 @@ Usage:
 OgreImporter <input file> <output file> [options]
 
 Options:
--a   Export animations
--m   Export morphs
--r   Export only rotations from animations
+-na  Do not output animations
+-nm  Do not output morphs
+-r   Output only rotations from animations
 -s   Split each submesh into own vertex buffer
 -t   Generate tangents
 \endverbatim
 
-Note: exporting only bone rotations may help when using an animation in a different model, but if bone position changes have been used for effect, the animation may become less lively. Unpredictable mutilations might result from using an animation in a model not originally intended for, as Urho3D does not specifically attempt to retarget animations.
+Note: outputting only bone rotations may help when using an animation in a different model, but if bone position changes have been used for effect, the animation may become less lively. Unpredictable mutilations might result from using an animation in a model not originally intended for, as Urho3D does not specifically attempt to retarget animations.
 
 \section Tools_PackageTool PackageTool
 

+ 1 - 0
Docs/ScriptAPI.dox

@@ -2115,6 +2115,7 @@ Properties:<br>
 - uint numAnimationStates (readonly)
 - AnimationState@[] animationStates (readonly)
 - uint numMorphs (readonly)
+- String[] morphNames (readonly)
 - float[] morphWeights
 - Zone@ zone (readonly)
 

+ 7 - 0
Engine/Engine/GraphicsAPI.cpp

@@ -613,6 +613,12 @@ static void AnimatedModelSetModel(Model* model, AnimatedModel* ptr)
     ptr->SetModel(model);
 }
 
+static const String& AnimatedModelGetMorphName(unsigned index, AnimatedModel* ptr)
+{
+    const Vector<ModelMorph>& morphs = ptr->GetMorphs();
+    return index < morphs.Size() ? morphs[index].name_ : String::EMPTY;
+}
+
 static void RegisterAnimatedModel(asIScriptEngine* engine)
 {
     RegisterRefCounted<AnimationState>(engine, "AnimationState");
@@ -660,6 +666,7 @@ static void RegisterAnimatedModel(asIScriptEngine* engine)
     engine->RegisterObjectMethod("AnimatedModel", "uint get_numAnimationStates() const", asMETHOD(AnimatedModel, GetNumAnimationStates), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedModel", "AnimationState@+ get_animationStates(const String&in) const", asMETHODPR(AnimatedModel, GetAnimationState, (const String&) const, AnimationState*), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedModel", "uint get_numMorphs() const", asMETHOD(AnimatedModel, GetNumMorphs), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimatedModel", "const String& get_morphNames(uint) const", asFUNCTION(AnimatedModelGetMorphName), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("AnimatedModel", "void set_morphWeights(const String&in, float)", asMETHODPR(AnimatedModel, SetMorphWeight, (const String&, float), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedModel", "float get_morphWeights(const String&in) const", asMETHODPR(AnimatedModel, GetMorphWeight, (const String&) const, float), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedModel", "Zone@+ get_zone() const", asMETHOD(AnimatedModel, GetZone), asCALL_THISCALL);

+ 8 - 2
Engine/Graphics/AnimatedModel.cpp

@@ -490,7 +490,10 @@ void AnimatedModel::SetMorphWeight(unsigned index, float weight)
             
             // Indexing might not be the same, so use the name hash instead
             for (unsigned i = 1; i < models.Size(); ++i)
-                models[i]->SetMorphWeight(morphs_[index].nameHash_, weight);
+            {
+                if (!models[i]->isMaster_)
+                    models[i]->SetMorphWeight(morphs_[index].nameHash_, weight);
+            }
         }
         
         MarkMorphsDirty();
@@ -535,7 +538,10 @@ void AnimatedModel::ResetMorphWeights()
         
         // Indexing might not be the same, so use the name hash instead
         for (unsigned i = 1; i < models.Size(); ++i)
-            models[i]->ResetMorphWeights();
+        {
+            if (!models[i]->isMaster_)
+                models[i]->ResetMorphWeights();
+        }
     }
     
     MarkMorphsDirty();

+ 4 - 4
Tools/AssetImporter/AssetImporter.cpp

@@ -177,8 +177,8 @@ void Run(const Vector<String>& arguments)
             "Usage: AssetImporter <command> <input file> <output file> [options]\n"
             "See http://assimp.sourceforge.net/main_features_formats.html for input formats\n\n"
             "Commands:\n"
-            "model Export a model\n"
-            "scene Export a scene\n"
+            "model Output a model\n"
+            "scene Output a scene\n"
             "dump  Dump scene node structure. No output file is generated\n"
             "lod   Combine several Urho3D models as LOD levels of the output model\n"
             "      Syntax: lod <dist0> <mdl0> <dist1 <mdl1> ... <output file>\n"
@@ -187,8 +187,8 @@ void Run(const Vector<String>& arguments)
             "-b    Save scene in binary format, default format is XML\n"
             "-i    Use local ID's for scene nodes\n"
             "-mX   Output a material list file X (model mode only)\n"
-            "-na   Do not export animations\n"
-            "-nm   Do not export materials\n"
+            "-na   Do not output animations\n"
+            "-nm   Do not output materials\n"
             "-ns   Do not create subdirectories for resources\n"
             "-nz   Do not create a zone and a directional light (scene mode only)\n"
             "-pX   Set path X for scene resources. Default is output file path\n"

+ 21 - 17
Tools/OgreImporter/OgreImporter.cpp

@@ -56,7 +56,7 @@ bool useOneBuffer_ = true;
 int main(int argc, char** argv);
 void Run(const Vector<String>& arguments);
 void LoadSkeleton(const String& skeletonFileName);
-void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool GetMorphs);
+void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool exportMorphs);
 void WriteOutput(const String& outputFileName, bool exportAnimations, bool rotationsOnly);
 void OptimizeIndices(ModelSubGeometryLodLevel* subGeom, ModelVertexBuffer* vb, ModelIndexBuffer* ib);
 void CalculateScore(ModelVertex& vertex);
@@ -82,18 +82,18 @@ void Run(const Vector<String>& arguments)
         ErrorExit(
             "Usage: OgreImporter <input file> <output file> [options]\n\n"
             "Options:\n"
-            "-a   Export animations\n"
-            "-m   Export morphs\n"
-            "-r   Export only rotations from animations\n"
+            "-na  Do not output animations\n"
+            "-nm  Do not output morphs\n"
+            "-r   Output only rotations from animations\n"
             "-s   Split each submesh into own vertex buffer\n"
             "-t   Generate tangents\n"
         );
     }
     
     bool generateTangents = false;
-    bool GetMorphs = false;
     bool splitSubMeshes = false;
-    bool exportAnimations = false;
+    bool exportAnimations = true;
+    bool exportMorphs = true;
     bool rotationsOnly = false;
     
     if (arguments.Size() > 2)
@@ -109,18 +109,20 @@ void Run(const Vector<String>& arguments)
                     generateTangents = true;
                     break;
                     
-                case 'a':
-                    exportAnimations = true;
+                case 'n':
+                    if (arg.Length() > 1)
+                    {
+                        if (arg[1] == 'a')
+                            exportAnimations = false;
+                        if (arg[1] == 'm')
+                            exportMorphs = false;
+                    }
                     break;
                     
                 case 'r':
                     rotationsOnly = true;
                     break;
                     
-                case 'm':
-                    GetMorphs = true;
-                    break;
-                    
                 case 's':
                     splitSubMeshes = true;
                     break;
@@ -129,7 +131,7 @@ void Run(const Vector<String>& arguments)
         }
     }
     
-    LoadMesh(arguments[0], generateTangents, splitSubMeshes, GetMorphs);
+    LoadMesh(arguments[0], generateTangents, splitSubMeshes, exportMorphs);
     WriteOutput(arguments[1], exportAnimations, rotationsOnly);
     
     PrintLine("Finished");
@@ -234,7 +236,7 @@ void LoadSkeleton(const String& skeletonFileName)
     }
 }
 
-void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool GetMorphs)
+void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool exportMorphs)
 {
     File meshFileSource(context_);
     meshFileSource.Open(inputFileName);
@@ -244,6 +246,8 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
     XMLElement root = meshFile_->GetRoot();
     XMLElement subMeshes = root.GetChild("submeshes");
     XMLElement skeletonLink = root.GetChild("skeletonlink");
+    if (root.IsNull())
+        ErrorExit("Could not load input file " + inputFileName);
     
     String skeletonName = skeletonLink.GetAttribute("name");
     if (!skeletonName.Empty())
@@ -470,7 +474,7 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
                 vBuf->elementMask_ |= MASK_BLENDWEIGHTS | MASK_BLENDINDICES;
                 bool sorted = false;
                 
-                // If amount of bones_ is larger than supported by HW skinning, must remap per submesh
+                // If amount of bones is larger than supported by HW skinning, must remap per submesh
                 if (bones_.Size() > MAX_SKIN_MATRICES)
                 {
                     Map<unsigned, unsigned> usedBoneMap;
@@ -494,7 +498,7 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
                         }
                     }
                     
-                    // If still too many bones_ in one subgeometry, error
+                    // If still too many bones in one subgeometry, error
                     if (usedBoneMap.Size() > MAX_SKIN_MATRICES)
                         ErrorExit("Too many bones in submesh " + String(subMeshIndex + 1));
                     
@@ -646,7 +650,7 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
     
     // Process poses/morphs
     // First find out all pose definitions
-    if (GetMorphs)
+    if (exportMorphs)
     {
         try
         {