Browse Source

Fix OBJ export in Drawable class. Fix wrong indexing in writing vertex colors in AssetImporter. Minor addition to documentation.

Lasse Öörni 9 years ago
parent
commit
2771411577

+ 1 - 1
Docs/Reference.dox

@@ -1117,7 +1117,7 @@ Note that the texcoord numbers are misleading as the actual texcoord inputs in s
 shader texcoord inputs 4-6.
 shader texcoord inputs 4-6.
 
 
 2) By defining VertexElement structures, which tell the data type, semantic, and zero-based semantic index (for e.g. multiple texcoords), and whether the data is per-vertex or per-instance data.
 2) By defining VertexElement structures, which tell the data type, semantic, and zero-based semantic index (for e.g. multiple texcoords), and whether the data is per-vertex or per-instance data.
-This allows to freely define the order and meaning of the elements.
+This allows to freely define the order and meaning of the elements. However for 3D objects, the first element should always be "Position" and use the Vector3 type to ensure e.g. raycasts and occlusion rendering work properly.
 
 
 The third parameter of \ref VertexBuffer::SetSize "SetSize()" is whether to create the buffer as static or dynamic. This is a hint to the underlying graphics API how to allocate the buffer data. Dynamic will suit frequent (every frame) modification better, while static has likely better overall performance for world geometry rendering.
 The third parameter of \ref VertexBuffer::SetSize "SetSize()" is whether to create the buffer as static or dynamic. This is a hint to the underlying graphics API how to allocate the buffer data. Dynamic will suit frequent (every frame) modification better, while static has likely better overall performance for world geometry rendering.
 
 

+ 1 - 1
Source/Tools/AssetImporter/AssetImporter.cpp

@@ -2288,7 +2288,7 @@ void WriteVertex(float*& dest, aiMesh* mesh, unsigned index, bool isSkinned, Bou
     for (unsigned i = 0; i < mesh->GetNumColorChannels() && i < MAX_CHANNELS; ++i)
     for (unsigned i = 0; i < mesh->GetNumColorChannels() && i < MAX_CHANNELS; ++i)
     {
     {
         *((unsigned*)dest) = Color(mesh->mColors[i][index].r, mesh->mColors[i][index].g, mesh->mColors[i][index].b,
         *((unsigned*)dest) = Color(mesh->mColors[i][index].r, mesh->mColors[i][index].g, mesh->mColors[i][index].b,
-            mesh->mColors[0][index].a).ToUInt();
+            mesh->mColors[i][index].a).ToUInt();
         ++dest;
         ++dest;
     }
     }
     
     

+ 25 - 18
Source/Urho3D/Graphics/Drawable.cpp

@@ -447,7 +447,6 @@ void Drawable::RemoveFromOctree()
 
 
 bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool asZUp, bool asRightHanded, bool writeLightmapUV)
 {
 {
-/*
     // Must track indices independently to deal with potential mismatching of drawables vertex attributes (ie. one with UV, another without, then another with)
     // Must track indices independently to deal with potential mismatching of drawables vertex attributes (ie. one with UV, another without, then another with)
     unsigned currentPositionIndex = 1;
     unsigned currentPositionIndex = 1;
     unsigned currentUVIndex = 1;
     unsigned currentUVIndex = 1;
@@ -486,28 +485,38 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
             // If we've reached here than we're going to actually write something to the OBJ file
             // If we've reached here than we're going to actually write something to the OBJ file
             anythingWritten = true;
             anythingWritten = true;
 
 
-            const unsigned char* vertexData = 0x0;
-            const unsigned char* indexData = 0x0;
-            unsigned int elementSize = 0, indexSize = 0, elementMask = 0;
-            geo->GetRawData(vertexData, elementSize, indexData, indexSize, elementMask);
+            const unsigned char* vertexData;
+            const unsigned char* indexData;
+            unsigned elementSize, indexSize;
+            const PODVector<VertexElement>* elements;
+            geo->GetRawData(vertexData, elementSize, indexData, indexSize, elements);
+            if (!vertexData || !elements)
+                continue;
+
+            bool hasPosition = VertexBuffer::HasElement(*elements, TYPE_VECTOR3, SEM_POSITION);
+            if (!hasPosition)
+            {
+                URHO3D_LOGERRORF("%s (%u) %s (%u) Geometry %u contains does not have Vector3 type positions in vertex data", node->GetName().Length() > 0 ? node->GetName().CString() : "Node", node->GetID(), drawable->GetTypeName().CString(), drawable->GetID(), geoIndex);
+                continue;
+            }
 
 
-            const bool hasNormals = (elementMask & MASK_NORMAL) != 0;
-            const bool hasUV = (elementMask & MASK_TEXCOORD1) != 0;
-            const bool hasLMUV = (elementMask & MASK_TEXCOORD2) != 0;
+            bool hasNormals = VertexBuffer::HasElement(*elements, TYPE_VECTOR3, SEM_NORMAL);
+            bool hasUV = VertexBuffer::HasElement(*elements, TYPE_VECTOR2, SEM_TEXCOORD, 0);
+            bool hasLMUV = VertexBuffer::HasElement(*elements, TYPE_VECTOR2, SEM_TEXCOORD, 1);
 
 
             if (elementSize > 0 && indexSize > 0)
             if (elementSize > 0 && indexSize > 0)
             {
             {
-                const unsigned vertexStart = geo->GetVertexStart();
-                const unsigned vertexCount = geo->GetVertexCount();
-                const unsigned indexStart = geo->GetIndexStart();
-                const unsigned indexCount = geo->GetIndexCount();
+                unsigned vertexStart = geo->GetVertexStart();
+                unsigned vertexCount = geo->GetVertexCount();
+                unsigned indexStart = geo->GetIndexStart();
+                unsigned indexCount = geo->GetIndexCount();
 
 
                 // Name NodeID DrawableType DrawableID GeometryIndex ("Geo" is included for clarity as StaticModel_32_2 could easily be misinterpreted or even quickly misread as 322)
                 // Name NodeID DrawableType DrawableID GeometryIndex ("Geo" is included for clarity as StaticModel_32_2 could easily be misinterpreted or even quickly misread as 322)
                 // Generated object name example: Node_5_StaticModel_32_Geo_0 ... or ... Bob_5_StaticModel_32_Geo_0
                 // Generated object name example: Node_5_StaticModel_32_Geo_0 ... or ... Bob_5_StaticModel_32_Geo_0
                 outputFile->WriteLine(String("o ").AppendWithFormat("%s_%u_%s_%u_Geo_%u", node->GetName().Length() > 0 ? node->GetName().CString() : "Node", node->GetID(), drawable->GetTypeName().CString(), drawable->GetID(), geoIndex));
                 outputFile->WriteLine(String("o ").AppendWithFormat("%s_%u_%s_%u_Geo_%u", node->GetName().Length() > 0 ? node->GetName().CString() : "Node", node->GetID(), drawable->GetTypeName().CString(), drawable->GetID(), geoIndex));
 
 
                 // Write vertex position
                 // Write vertex position
-                const unsigned positionOffset = VertexBuffer::GetElementOffset(elementMask, ELEMENT_POSITION);
+                unsigned positionOffset = VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_POSITION);
                 for (unsigned j = 0; j < vertexCount; ++j)
                 for (unsigned j = 0; j < vertexCount; ++j)
                 {
                 {
                     Vector3 vertexPosition = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + positionOffset]));
                     Vector3 vertexPosition = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + positionOffset]));
@@ -527,7 +536,7 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
 
 
                 if (hasNormals)
                 if (hasNormals)
                 {
                 {
-                    const unsigned normalOffset = VertexBuffer::GetElementOffset(elementMask, ELEMENT_NORMAL);
+                    unsigned normalOffset = VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR3, SEM_NORMAL);
                     for (unsigned j = 0; j < vertexCount; ++j)
                     for (unsigned j = 0; j < vertexCount; ++j)
                     {
                     {
                         Vector3 vertexNormal = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + normalOffset]));
                         Vector3 vertexNormal = *((const Vector3*)(&vertexData[(vertexStart + j) * elementSize + normalOffset]));
@@ -551,7 +560,7 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
                 if (hasUV || (hasLMUV && writeLightmapUV))
                 if (hasUV || (hasLMUV && writeLightmapUV))
                 {
                 {
                     // if writing Lightmap UV is chosen, only use it if TEXCOORD2 exists, otherwise use TEXCOORD1
                     // if writing Lightmap UV is chosen, only use it if TEXCOORD2 exists, otherwise use TEXCOORD1
-                    const unsigned texCoordOffset = (writeLightmapUV && hasLMUV) ? VertexBuffer::GetElementOffset(elementMask, ELEMENT_TEXCOORD2) : VertexBuffer::GetElementOffset(elementMask, ELEMENT_TEXCOORD1);
+                    unsigned texCoordOffset = (writeLightmapUV && hasLMUV) ? VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR2, SEM_TEXCOORD, 1) : VertexBuffer::GetElementOffset(*elements, TYPE_VECTOR2, SEM_TEXCOORD, 9);
                     for (unsigned j = 0; j < vertexCount; ++j)
                     for (unsigned j = 0; j < vertexCount; ++j)
                     {
                     {
                         Vector2 uvCoords = *((const Vector2*)(&vertexData[(vertexStart + j) * elementSize + texCoordOffset]));
                         Vector2 uvCoords = *((const Vector2*)(&vertexData[(vertexStart + j) * elementSize + texCoordOffset]));
@@ -612,7 +621,7 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
                     }
                     }
                     else if (hasNormals || hasUV)
                     else if (hasNormals || hasUV)
                     {
                     {
-                        const unsigned secondTraitIndex = hasNormals ? currentNormalIndex : currentUVIndex;
+                        unsigned secondTraitIndex = hasNormals ? currentNormalIndex : currentUVIndex;
                         output.AppendWithFormat("%l%s%l %l%s%l %l%s%l",
                         output.AppendWithFormat("%l%s%l %l%s%l %l%s%l",
                             currentPositionIndex + longIndices[0],
                             currentPositionIndex + longIndices[0],
                             slashCharacter.CString(),
                             slashCharacter.CString(),
@@ -643,8 +652,6 @@ bool WriteDrawablesToOBJ(PODVector<Drawable*> drawables, File* outputFile, bool
         }
         }
     }
     }
     return anythingWritten;
     return anythingWritten;
-*/
-    return true;
 }
 }
 
 
 }
 }