/****************************************************************************** libx42make - skinned vertex animation library (exporter utilities) Copyright (C) 2007 HermitWorks Entertainment Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA. ******************************************************************************/ #ifndef INC_LIBX42MAKE_BATCHER_H #define INC_LIBX42MAKE_BATCHER_H namespace x42 { namespace make { class BoneTopology { friend class ModelData; public: struct Entry { ConstBonePtr bone; ConstBonePtr parent; std::vector< ConstBonePtr > children; ConstBonePtr localRoot; uint distanceToLocalRoot; ConstBonePtr nearestLeaf; ConstBonePtr pathToNearestLeaf; uint distanceToNearestLeaf; bool IsRoot( void ) const { return parent == ConstBonePtr(); } bool IsLeaf( void ) const { return children.size() == 0; } uint NumNeighbors( void ) const { return (IsRoot() ? 0 : 1) + (uint)children.size(); } }; std::vector< Entry > entries; std::vector< ConstBonePtr > roots; std::vector< ConstBonePtr > leaves; BoneTopology( const std::vector< BonePtr > &bones ); BoneTopology( const std::vector< ConstBonePtr > &bones ); uint NumEntries( void ) const { return (uint)entries.size(); } const Entry& operator [] ( uint index ) const { return entries[index]; } const Entry& operator [] ( ConstBonePtr bone ) const { return entries[bone->index]; } private: void ProcessBone( ConstBonePtr bone ); void ProcessEntries( void ); }; class Adjacency { public: Adjacency( void ) { } Adjacency( const std::vector< index > &tris ) { Init( tris ); } void Init( const std::vector< index > &tris ); const uint* AdjBegin( uint tri ) const { return &values[0] + entries[tri].begin; } const uint* AdjEnd( uint tri ) const { return &values[0] + entries[tri].begin + entries[tri].length; } private: struct AdjEntry { uint begin; uint length; }; std::vector< AdjEntry > entries; std::vector< uint > values; }; class TopologicalSplitter { public: TopologicalSplitter( ConstGroupPtr group, uint maxVerts = DEFAULT_MAX_VERTS, uint maxPrims = DEFAULT_MAX_PRIMS, uint maxInfluences = DEFAULT_MAX_INFLUENCES ); void AddUnvisitedSetsInOrder( void ); void AddSetsStartingAtLeaves( void ); void AddSetsStartingAtRoot( void ); void AddAdjacencySet( uint startingTri ); void FixupWeights( void ); GroupPtr GoodGroup( void ) { return goodGroup; } GroupPtr SpilloverGroup( void ) { return spillGroup; } private: friend struct TriCmp; struct Tri { uint idx; uint addInfs; uint addVerts; bool visited; Tri( void ) : visited( false ) { } }; ConstGroupPtr group; uint maxVerts, maxPrims, maxInfluences; Adjacency adj; std::vector< index > triIndices; std::vector< Tri > triangles; GroupPtr goodGroup; std::vector< uint > goodInfMap; std::vector< index > goodVertMap; GroupPtr spillGroup; std::vector< uint > spillInfMap; std::vector< index > spillVertMap; void ResolvePointReps( std::vector< index > &indices ); void InternalAddSets( std::vector< ConstBonePtr > &toVisit, bool favorRoot, const BoneTopology &topology ); void UpdateTriList( void ); void AddTriangle( const Tri &tri ); }; }; }; #endif