Browse Source

Added geometry data serialization for CustomGeometry.

Lasse Öörni 12 years ago
parent
commit
02b178020e

+ 88 - 1
Engine/Graphics/CustomGeometry.cpp

@@ -28,10 +28,13 @@
 #include "Geometry.h"
 #include "Log.h"
 #include "Material.h"
+#include "MemoryBuffer.h"
 #include "Node.h"
 #include "OcclusionBuffer.h"
 #include "OctreeQuery.h"
 #include "Profiler.h"
+#include "ResourceCache.h"
+#include "VectorBuffer.h"
 #include "VertexBuffer.h"
 
 #include "DebugNew.h"
@@ -47,7 +50,8 @@ CustomGeometry::CustomGeometry(Context* context) :
     Drawable(context, DRAWABLE_GEOMETRY),
     vertexBuffer_(new VertexBuffer(context)),
     elementMask_(MASK_POSITION),
-    geometryIndex_(0)
+    geometryIndex_(0),
+    materialsAttr_(Material::GetTypeStatic())
 {
     vertexBuffer_->SetShadowed(true);
     SetNumGeometries(1);
@@ -62,6 +66,8 @@ void CustomGeometry::RegisterObject(Context* context)
     context->RegisterFactory<CustomGeometry>(STATIC_CATEGORY);
     
     ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BUFFER, "Geometry Data", GetGeometryDataAttr, SetGeometryDataAttr, PODVector<unsigned char>, Variant::emptyBuffer, AM_FILE|AM_NOEDIT);
+    REF_ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_RESOURCEREFLIST, "Materials", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
     ATTRIBUTE(CustomGeometry, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CustomGeometry, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
     ATTRIBUTE(CustomGeometry, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
@@ -380,6 +386,87 @@ Material* CustomGeometry::GetMaterial(unsigned index) const
     return index < batches_.Size() ? batches_[index].material_ : (Material*)0;
 }
 
+void CustomGeometry::SetGeometryDataAttr(PODVector<unsigned char> data)
+{
+    if (!data.Size())
+        return;
+    
+    MemoryBuffer buffer(data);
+    
+    SetNumGeometries(buffer.ReadVLE());
+    elementMask_ = buffer.ReadUInt();
+    
+    for (unsigned i = 0; i < geometries_.Size(); ++i)
+    {
+        unsigned numVertices = buffer.ReadVLE();
+        vertices_[i].Resize(numVertices);
+        primitiveTypes_[i] = (PrimitiveType)buffer.ReadUByte();
+        
+        for (unsigned j = 0; j < numVertices; ++j)
+        {
+             if (elementMask_ & MASK_POSITION)
+                vertices_[i][j].position_ = buffer.ReadVector3();
+             if (elementMask_ & MASK_NORMAL)
+                vertices_[i][j].normal_ = buffer.ReadVector3();
+             if (elementMask_ & MASK_COLOR)
+                vertices_[i][j].color_ = buffer.ReadUInt();
+             if (elementMask_ & MASK_TEXCOORD1)
+                vertices_[i][j].texCoord_ = buffer.ReadVector2();
+             if (elementMask_ & MASK_TANGENT)
+                vertices_[i][j].tangent_ = buffer.ReadVector4();
+        }
+    }
+    
+    Commit();
+}
+
+void CustomGeometry::SetMaterialsAttr(const ResourceRefList& value)
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    for (unsigned i = 0; i < value.ids_.Size(); ++i)
+        SetMaterial(i, cache->GetResource<Material>(value.ids_[i]));
+}
+
+PODVector<unsigned char> CustomGeometry::GetGeometryDataAttr() const
+{
+    VectorBuffer ret;
+    
+    ret.WriteVLE(geometries_.Size());
+    ret.WriteUInt(elementMask_);
+    
+    for (unsigned i = 0; i < geometries_.Size(); ++i)
+    {
+        unsigned numVertices = vertices_[i].Size();
+        ret.WriteVLE(numVertices);
+        ret.WriteUByte(primitiveTypes_[i]);
+        
+        for (unsigned j = 0; j < numVertices; ++j)
+        {
+             if (elementMask_ & MASK_POSITION)
+                ret.WriteVector3(vertices_[i][j].position_);
+             if (elementMask_ & MASK_NORMAL)
+                ret.WriteVector3(vertices_[i][j].normal_);
+             if (elementMask_ & MASK_COLOR)
+                ret.WriteUInt(vertices_[i][j].color_);
+             if (elementMask_ & MASK_TEXCOORD1)
+                ret.WriteVector2(vertices_[i][j].texCoord_);
+             if (elementMask_ & MASK_TANGENT)
+                ret.WriteVector4(vertices_[i][j].tangent_);
+        }
+    }
+    
+    return ret.GetBuffer();
+}
+
+const ResourceRefList& CustomGeometry::GetMaterialsAttr() const
+{
+    materialsAttr_.ids_.Resize(batches_.Size());
+    for (unsigned i = 0; i < batches_.Size(); ++i)
+        materialsAttr_.ids_[i] = batches_[i].material_ ? batches_[i].material_->GetNameHash() : StringHash();
+    
+    return materialsAttr_;
+}
+
 void CustomGeometry::OnWorldBoundingBoxUpdate()
 {
     worldBoundingBox_ = boundingBox_.Transformed(node_->GetWorldTransform());

+ 11 - 0
Engine/Graphics/CustomGeometry.h

@@ -94,6 +94,15 @@ public:
     /// Return material by geometry index.
     Material* GetMaterial(unsigned index) const;
     
+    /// Set geometry data attribute.
+    void SetGeometryDataAttr(PODVector<unsigned char> data);
+    /// Set materials attribute.
+    void SetMaterialsAttr(const ResourceRefList& value);
+    /// Return geometry data attribute.
+    PODVector<unsigned char> GetGeometryDataAttr() const;
+    /// Return materials attribute.
+    const ResourceRefList& GetMaterialsAttr() const;
+    
 protected:
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
@@ -113,6 +122,8 @@ private:
     unsigned elementMask_;
     /// Current geometry being updated.
     unsigned geometryIndex_;
+    /// Material list attribute.
+    mutable ResourceRefList materialsAttr_;
 };
 
 }

+ 1 - 1
Engine/Navigation/NavigationMesh.h

@@ -150,7 +150,7 @@ public:
     
     /// Set navigation data attribute.
     void SetNavigationDataAttr(PODVector<unsigned char> data);
-    /// Get navigation data attribute.
+    /// Return navigation data attribute.
     PODVector<unsigned char> GetNavigationDataAttr() const;
     
 private: