/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NGEOMETRY__ #define __NGEOMETRY__ #include "core/tangent_frame.h" #include "geometry/bounding_box.h" #include "color/color.h" #include "memory/nshared_ptr.h" #include "memory/nauto_ptr.h" #include "memory/bit_field.h" #include "nstring/nstring.h" namespace GS { namespace Core { using namespace NML; //------------------------------------------------------------------------------ struct GeometrySkin { float w[__PV_BONE_LIMIT__]; ushort bone_index[__PV_BONE_LIMIT__]; }; struct Polygon { ushort vtx_count; ushort material; uint *binding; }; struct VertexToPolygon { ushort pol_count; Array pol_index; }; struct PolygonVertex { uint pol_index; uint vtx_index; }; struct VertexToVertex { ushort vtx_count; Array vtx; }; typedef Polygon * pPolygon; //------------------------------------------------------------------------------ /*! @short Geometry class. @author Emmanuel Julien (ejulien@gsworks.fr) */ class Geometry : public SharedObject { public: NPLACEMENT_NEW(Geometry) /// Item flag. enum { FlagHidden = (1 << 0), FlagNullLodProxy = (1 << 1), FlagNullShadowProxy = (1 << 2), // Non-serialized. FlagNoMaterialCache = (1 << 3) }; private: /// Low-level vertex properties comparison. char VertexPropertiesCompare(uint, uint, uint, uint, uint); /*! @name Serialization @{ */ void ParseVertex(const Tag *); void ParseAsciiVertex(const Tag *); void ParseSkin(const Tag *); void ParsePolygon(const Tag *); void ParseAsciiPolygon(const Tag *); void ParsePolygonNormal(const Tag *); void ParseVertexNormal(const Tag *); void ParseVertexTangent(const Tag *); void ParseRGB(const Tag *); void ParseAsciiRGB(const Tag *); void ParseUV(const Tag *); void ParseAsciiUV(const Tag *); void ParseMaterials(const Tag *); void ParseMisc(const Tag &); /// @} public: String name; BitField flag; String copy_lock; ///< Used to prevent publishing. /*! @name Proxies. @{ */ String lod_proxy; ///< LOD proxy geometry. float lod_distance; ///< LOD distance. String shadow_proxy; ///< Shadow proxy geometry. /// @} /// Return the number of triangles in the mesh. Note: this does not perform any conversion. uint GetTriangleCount() const { uint n, c = 0; for (n = 0; n < pol.GetCount(); ++n) if (pol[n].vtx_count >= 3) c += pol[n].vtx_count - 2; return c; } /*! @short Flag vertices sharing the same properties as homogeneous. All vertices attributes are checked and compared. If they all lie under a given threshold then the vertex is reported as homogeneous. This function is heavily used by the geometry stripper and triangle list builder. @param material_index Optionally restrict attribute comparison to one material only. (default: -1 to include all materials in the geometry.) */ void FlagHomogeneousVertex(Array &flag, const Array &polygon_index, const Array &, int material_index = -1) const; /*! @name Topology section. @{ */ /// Compute the geometry min-max from current vertex set (AABB). MinMax ComputeMinMax(const Matrix4 * = 0) const; /// Compute geometry bones bounding volumes. bool ComputeBoneBoundingVolumes(Array &) const; Array vtx, vtx_normal; Array vtx_tangent; Array rgb; Array uv[__UV_PER_GEOMETRY__]; /// Return the number of UV channels used by the geometry. uint GetUVCount() const; Array pol; Array binding; bool AllocateVertex(uint); bool AllocatePolygon(uint); /// Allocate polygon binding array. bool AllocatePolygonBinding(); /// Compute polygon binding count. uint ComputePolygonBindingCount() const; /// @} /*! @name Skinning section. @{ */ /// Allocate bones array (not the skin weights array). bool AllocateBone(uint); /// Return the number of bones referenced by the geometry. uint GetBoneCount() const; Array bone_name; Array bone_bind_matrix; Array skin; ///< Skin weights. /// @} Array pol_normal; Array pol_tangent; bool ComputePolygonNormal(bool force = false); bool ComputePolygonTangent(uint uv_index = 0, bool force = false); bool ComputeVertexNormal(float msa = -1.f, bool force = false); bool ComputeVertexNormal(Array &, float msa = -1.f); bool ComputeVertexTangent(bool reverse_t = false, bool reverse_b = false, bool force = false); /*! @name Geometry tools. @{ */ /// Compute polygon start index. void ComputePolygonIndex(Array &) const; /// Compute vertex to polygon table. void ComputeVertexToPolygon(Array &) const; /// Compute vertex to vertex table. void ComputeVertexToVertex(Array &, const Array * = 0) const; /// @} void SmoothRGB(uint pass_count, float max_smooth_angle); void FreeRGB(); void FreeUV(); /*! @name Material section. @{ */ struct MaterialSlot { String name; bool use_cache; MaterialSlot() : use_cache(true) {} }; Array material_table; /// Merge duplicate materials in table. uint MergeDuplicateMaterials(); /// @} void Free(); /*! @name Serialization. @{ */ bool FromMetaTag(const Tag &); Tag *AsMetaTag() const; /// @} Geometry(); virtual ~Geometry(); }; /// Compute the minmax of a vertex array. extern bool ComputeVertexArrayMinMax(const Array &, MinMax &, const Matrix4 * = 0); typedef SharedPtr sGeometry; typedef Geometry * pGeometry; } // Core } // GS #endif // __NGEOMETRY__