Sirikata
|
00001 /* Sirikata 00002 * Meshdata.hpp 00003 * 00004 * Copyright (c) 2010, Daniel B. Miller 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifndef _SIRIKATA_MESH_MESHDATA_HPP_ 00034 #define _SIRIKATA_MESH_MESHDATA_HPP_ 00035 00036 #include <sirikata/mesh/Platform.hpp> 00037 #include <sirikata/mesh/Visual.hpp> 00038 #include <sirikata/core/transfer/RemoteFileMetadata.hpp> 00039 #include "LightInfo.hpp" 00040 #include <stack> 00041 00042 namespace Sirikata { 00043 namespace Mesh { 00044 00045 // Typedefs for NodeIndices, which refer to scene graph nodes in the model 00046 typedef int32 NodeIndex; 00047 extern SIRIKATA_MESH_EXPORT NodeIndex NullNodeIndex; 00048 typedef std::vector<NodeIndex> NodeIndexList; 00049 00050 00051 typedef std::vector<LightInfo> LightInfoList; 00052 typedef std::vector<std::string> TextureList; 00053 00054 struct Meshdata; 00055 typedef std::tr1::shared_ptr<Meshdata> MeshdataPtr; 00056 typedef std::tr1::weak_ptr<Meshdata> MeshdataWPtr; 00057 00061 struct SIRIKATA_MESH_EXPORT SkinController { 00062 // Joints for this controls Indexes into the Meshdata.joints array 00063 // (which indexes into Meshdata.nodes). 00064 std::vector<uint32> joints; 00065 00066 Matrix4x4f bindShapeMatrix; 00069 std::vector<unsigned int> weightStartIndices; 00070 // weights and jointIndices are the same size and are a sparse 00071 // representation of the (vertex,bone) = weight matrix: the 00072 // weightStartIndices let you figure out the range in these arrays that 00073 // correspond to a single vertex. In that range, each pair represents the 00074 // weight for one joint for the current vertex, with the rest of the joints 00075 // having weight 0. 00076 std::vector<float> weights; 00077 std::vector<unsigned int>jointIndices; 00078 // One inverse bind matrix per joint. 00079 std::vector<Matrix4x4f> inverseBindMatrices; 00080 }; 00081 typedef std::vector<SkinController> SkinControllerList; 00082 00083 struct SIRIKATA_MESH_EXPORT SubMeshGeometry { 00084 std::string name; 00085 00086 std::vector<Sirikata::Vector3f> positions; 00087 std::vector<Sirikata::Vector3f> normals; 00088 std::vector<Sirikata::Vector3f> tangents; 00089 std::vector<Sirikata::Vector4f> colors; 00090 00091 struct TextureSet { 00092 unsigned int stride; 00093 std::vector<float> uvs; 00094 }; 00095 std::vector<TextureSet>texUVs; 00096 struct Primitive { 00097 std::vector<unsigned short> indices; 00098 00099 enum PrimitiveType { 00100 TRIANGLES, 00101 LINES, 00102 POINTS, 00103 LINESTRIPS, 00104 TRISTRIPS, 00105 TRIFANS 00106 }primitiveType; 00107 typedef size_t MaterialId; 00108 MaterialId materialId; 00109 }; 00110 std::vector<Primitive> primitives; 00111 00112 BoundingBox3f3f aabb; 00113 double radius; 00114 void recomputeBounds(); 00115 00116 SkinControllerList skinControllers; 00117 00118 00123 void append(const SubMeshGeometry& rhs, const Matrix4x4f& xform); 00124 }; 00125 typedef std::vector<SubMeshGeometry> SubMeshGeometryList; 00126 00127 00128 struct SIRIKATA_MESH_EXPORT GeometryInstance { 00129 typedef std::map<SubMeshGeometry::Primitive::MaterialId,size_t> MaterialBindingMap; 00130 MaterialBindingMap materialBindingMap;//maps materialIndex to offset in Meshdata's materials 00131 unsigned int geometryIndex; // Index in SubMeshGeometryList 00132 NodeIndex parentNode; // Index of node holding this instance 00133 00138 BoundingBox3f3f computeTransformedBounds(MeshdataPtr parent, const Matrix4x4f& xform) const; 00139 BoundingBox3f3f computeTransformedBounds(const Meshdata& parent, const Matrix4x4f& xform) const; 00140 void computeTransformedBounds(MeshdataPtr parent, const Matrix4x4f& xform, BoundingBox3f3f* bounds_out, double* radius_out) const; 00141 void computeTransformedBounds(const Meshdata& parent, const Matrix4x4f& xform, BoundingBox3f3f* bounds_out, double* radius_out) const; 00142 }; 00143 typedef std::vector<GeometryInstance> GeometryInstanceList; 00144 00145 struct SIRIKATA_MESH_EXPORT LightInstance { 00146 int lightIndex; // Index in LightInfoList 00147 NodeIndex parentNode; // Index of node holding this instance 00148 }; 00149 typedef std::vector<LightInstance> LightInstanceList; 00150 00151 struct SIRIKATA_MESH_EXPORT MaterialEffectInfo { 00152 struct Texture { 00153 std::string uri; 00154 Vector4f color;//color while the texture is pulled in, or if the texture is 404'd 00155 size_t texCoord; 00156 enum Affecting { 00157 DIFFUSE, 00158 SPECULAR, 00159 EMISSION, 00160 AMBIENT, 00161 REFLECTIVE, 00162 OPACITY, 00163 00164 }affecting; 00165 enum SamplerType 00166 { 00167 SAMPLER_TYPE_UNSPECIFIED, 00168 SAMPLER_TYPE_1D, 00169 SAMPLER_TYPE_2D, 00170 SAMPLER_TYPE_3D, 00171 SAMPLER_TYPE_CUBE, 00172 SAMPLER_TYPE_RECT, 00173 SAMPLER_TYPE_DEPTH, 00174 SAMPLER_TYPE_STATE 00175 } samplerType; 00176 enum SamplerFilter 00177 { 00178 SAMPLER_FILTER_UNSPECIFIED, 00179 SAMPLER_FILTER_NONE, 00180 SAMPLER_FILTER_NEAREST, 00181 SAMPLER_FILTER_LINEAR, 00182 SAMPLER_FILTER_NEAREST_MIPMAP_NEAREST, 00183 SAMPLER_FILTER_LINEAR_MIPMAP_NEAREST, 00184 SAMPLER_FILTER_NEAREST_MIPMAP_LINEAR, 00185 SAMPLER_FILTER_LINEAR_MIPMAP_LINEAR 00186 }; 00187 SamplerFilter minFilter; 00188 SamplerFilter magFilter; 00189 enum WrapMode 00190 { 00191 WRAP_MODE_UNSPECIFIED=0, 00192 // NONE == GL_CLAMP_TO BORDER The defined behavior for NONE is 00193 // consistent with decal texturing where the border is black. 00194 // Mapping this calculation to GL_CLAMP_TO_BORDER is the best 00195 // approximation of this. 00196 WRAP_MODE_NONE, 00197 // WRAP == GL_REPEAT Ignores the integer part of texture coordinates, 00198 // using only the fractional part. 00199 WRAP_MODE_WRAP, 00200 // MIRROR == GL_MIRRORED_REPEAT First mirrors the texture coordinate. 00201 // The mirrored coordinate is then clamped as described for CLAMP_TO_EDGE. 00202 WRAP_MODE_MIRROR, 00203 // CLAMP == GL_CLAMP_TO_EDGE Clamps texture coordinates at all 00204 // mipmap levels such that the texture filter never samples a 00205 // border texel. Note: GL_CLAMP takes any texels beyond the 00206 // sampling border and substitutes those texels with the border 00207 // color. So CLAMP_TO_EDGE is more appropriate. This also works 00208 // much better with OpenGL ES where the GL_CLAMP symbol was removed 00209 // from the OpenGL ES specification. 00210 WRAP_MODE_CLAMP, 00211 // BORDER GL_CLAMP_TO_BORDER Clamps texture coordinates at all 00212 // MIPmaps such that the texture filter always samples border 00213 // texels for fragments whose corresponding texture coordinate 00214 // is sufficiently far outside the range [0, 1]. 00215 WRAP_MODE_BORDER 00216 }; 00217 WrapMode wrapS,wrapT,wrapU; 00218 unsigned int maxMipLevel; 00219 float mipBias; 00220 00221 bool operator==(const Texture& rhs) const; 00222 bool operator!=(const Texture& rhs) const; 00223 }; 00224 typedef std::vector<Texture> TextureList; 00225 TextureList textures; 00226 float shininess; 00227 float reflectivity; 00228 00229 bool operator==(const MaterialEffectInfo& rhs) const; 00230 bool operator!=(const MaterialEffectInfo& rhs) const; 00231 }; 00232 typedef std::vector<MaterialEffectInfo> MaterialEffectInfoList; 00233 00234 00235 struct SIRIKATA_MESH_EXPORT InstanceSkinAnimation { 00236 }; 00237 00239 struct SIRIKATA_MESH_EXPORT TransformationKeyFrames { 00240 typedef std::vector<float> TimeList; 00241 TimeList inputs; 00242 typedef std::vector<Matrix4x4f> TransformationList; 00243 TransformationList outputs; 00244 }; 00245 00246 // A scene graph node. Contains a transformation, set of children nodes, 00247 // camera instances, geometry instances, skin controller instances, light 00248 // instances, and instances of other nodes. 00249 struct SIRIKATA_MESH_EXPORT Node { 00250 Node(); 00251 Node(NodeIndex par, const Matrix4x4f& xform); 00252 Node(const Matrix4x4f& xform); 00253 00254 bool containsInstanceController; 00255 00256 // Parent node in the actual hierarchy (not instantiated). 00257 NodeIndex parent; 00258 // Transformation to apply when traversing this node. 00259 Matrix4x4f transform; 00260 // Direct children, i.e. they are contained by this node directly and their 00261 // parent NodeIndex will reflect that. 00262 NodeIndexList children; 00263 // Instantiations of other nodes (and their children) into this 00264 // subtree. Because they are instantiations, their 00265 // instanceChildren[i]->parent != this node's index. 00266 NodeIndexList instanceChildren; 00267 00268 // Map of name -> animation curve. 00269 typedef std::map<String, TransformationKeyFrames> AnimationMap; 00270 AnimationMap animations; 00271 }; 00272 typedef std::vector<Node> NodeList; 00273 00274 //Stores information about a single mipmap level 00275 struct SIRIKATA_MESH_EXPORT ProgressiveMipmapLevel { 00276 //Offset within the tar file of the mipmap 00277 uint32 offset; 00278 //Length of the mipmap file within the tar file 00279 uint32 length; 00280 //Width of the mipmap image 00281 uint32 width; 00282 //Height of the mipmap image 00283 uint32 height; 00284 }; 00285 //A map containing mipmap levels in an archive 00286 typedef std::map<uint32, ProgressiveMipmapLevel> ProgressiveMipmaps; 00287 //Information about an archive of mipmaps 00288 struct SIRIKATA_MESH_EXPORT ProgressiveMipmapArchive { 00289 //Contains the list of mipmap levels 00290 ProgressiveMipmaps mipmaps; 00291 //The name of the image in the mesh that references this 00292 std::string name; 00293 //The hash of the mipmap archive 00294 Transfer::Fingerprint archiveHash; 00295 }; 00296 //A map containing the names of mipmap archives 00297 typedef std::map<std::string, ProgressiveMipmapArchive> ProgressiveMipmapMap; 00298 //Stores progressive mesh information 00299 struct SIRIKATA_MESH_EXPORT ProgressiveData { 00300 //The hash of the progressive stream 00301 Transfer::Fingerprint progressiveHash; 00302 //The number of triangles in the progressive stream 00303 uint32 numProgressiveTriangles; 00304 //Maps the names of mipmap archives to the mipmap archive data 00305 ProgressiveMipmapMap mipmaps; 00306 }; 00307 typedef std::tr1::shared_ptr<ProgressiveData> ProgressiveDataPtr; 00308 00309 struct SIRIKATA_MESH_EXPORT Meshdata : public Visual { 00310 private: 00311 static String sType; 00312 00313 public: 00314 Meshdata(); 00315 00316 virtual ~Meshdata(); 00317 00318 virtual const String& type() const; 00319 00320 SubMeshGeometryList geometry; 00321 TextureList textures; 00322 LightInfoList lights; 00323 MaterialEffectInfoList materials; 00324 00325 long id; 00326 00327 bool hasAnimations; 00328 00329 GeometryInstanceList instances; 00330 LightInstanceList lightInstances; 00331 00332 // The global transform should be applied to all nodes and instances 00333 Matrix4x4f globalTransform; 00334 // We track two sets of nodes: roots and the full list. (Obviously the roots 00335 // are a subset of the full list). The node list is just the full set, 00336 // usually only used to look up children/parents. The roots list is just a 00337 // set of indices into the full list. 00338 NodeList nodes; 00339 NodeIndexList rootNodes; 00340 00341 //Stores a list of transforms on the path from the scene root 00342 //to the instance controller for the skeleton. 00343 std::vector<Matrix4x4f> mInstanceControllerTransformList; 00344 // Joints are tracked as indices of the nodes they are associated with. 00345 NodeIndexList joints; 00346 00347 // Be careful using these methods. Since there are no "parent" links for 00348 // instance nodes (and even if there were, there could be more than one), 00349 // these methods cannot correctly compute the transform when instance_nodes 00350 // are involved. 00351 Matrix4x4f getTransform(NodeIndex index) const; 00352 00353 // If this mesh is in progressive format, stores progressive information 00354 ProgressiveDataPtr progressiveData; 00355 00356 private: 00357 00358 // A stack of NodeState is used to track the current traversal state for 00359 // instance iterators 00360 struct SIRIKATA_MESH_EXPORT NodeState { 00361 enum Step { 00362 Init, 00363 Nodes, 00364 InstanceNodes, 00365 InstanceGeometries, 00366 InstanceLights, 00367 Done 00368 }; 00369 00370 NodeIndex index; 00371 Matrix4x4f transform; 00372 Step step; 00373 int32 currentChild; 00374 }; 00375 struct SIRIKATA_MESH_EXPORT JointNodeState : public NodeState { 00376 uint32 joint_id; 00377 std::vector<Matrix4x4f> transformList; 00378 }; 00379 public: 00380 00381 // Allows you to generate a list of GeometryInstances with their transformations. 00382 class SIRIKATA_MESH_EXPORT GeometryInstanceIterator { 00383 public: 00384 GeometryInstanceIterator(const Meshdata* const mesh); 00385 // Get the next GeometryInstance and its transform. Returns true if 00386 // values were set, false if there were no more instances. The index 00387 // returned is of the geometry instance. 00388 bool next(uint32* geoinst_idx, Matrix4x4f* xform); 00389 private: 00390 const Meshdata* mMesh; 00391 00392 int32 mRoot; 00393 std::stack<NodeState> mStack; 00394 }; 00395 GeometryInstanceIterator getGeometryInstanceIterator() const; 00399 uint32 getInstancedGeometryCount() const; 00400 00401 00402 // Allows you to generate a list of joints with their transformations. 00403 class SIRIKATA_MESH_EXPORT JointIterator { 00404 public: 00405 JointIterator(const Meshdata* const mesh); 00406 // Get the next Joint's unique ID, its index in the list of joints, its 00407 // transform, and parent joint ID. Also gets the list of transforms from the root node 00408 // to the instance controller of the skeleton referencing the joint. Returns true if 00409 // values were set, false if there were no more joints. Joint IDs are 00410 // non-zero, so you can check for, e.g., no parent with parent_id == 0 00411 // or if (parent_id). The joint_idx is an index into Meshdata::joints. 00412 bool next(uint32* joint_id, uint32* joint_idx, Matrix4x4f* xform, uint32* parent_id, std::vector<Matrix4x4f>& transformList); 00413 private: 00414 const Meshdata* mMesh; 00415 00416 int32 mRoot; 00417 std::stack<JointNodeState> mStack; 00418 uint32 mNextID; 00419 }; 00420 JointIterator getJointIterator() const; 00424 uint32 getJointCount() const; 00425 00426 00427 // Allows you to generate a list of GeometryInstances with their transformations. 00428 class SIRIKATA_MESH_EXPORT LightInstanceIterator { 00429 public: 00430 LightInstanceIterator(const Meshdata* const mesh); 00431 // Get the next LightInstance and its transform. Returns true if 00432 // values were set, false if there were no more instances. The index 00433 // returned is of the light instance. 00434 bool next(uint32* lightinst_idx, Matrix4x4f* xform); 00435 private: 00436 const Meshdata* mMesh; 00437 00438 int32 mRoot; 00439 std::stack<NodeState> mStack; 00440 }; 00441 LightInstanceIterator getLightInstanceIterator() const; 00446 uint32 getInstancedLightCount() const; 00447 }; 00448 00449 } // namespace Mesh 00450 } // namespace Sirikata 00451 00452 #endif //_SIRIKATA_MESH_MESHDATA_HPP_