/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation 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 SE_INCL_MESH_H #define SE_INCL_MESH_H #ifdef PRAGMA_ONCE #pragma once #endif #include <Engine/Base/CTString.h> #include <Engine/Base/Serial.h> #include <Engine/Math/Vector.h> #include <Engine/Math/Placement.h> #include <Engine/Templates/DynamicArray.h> #include <Engine/Templates/StaticArray.h> #include <Engine/Graphics/Texture.h> #include <Engine/Graphics/Shader.h> #define ML_HALF_FACE_FORWARD (1UL<<0) // half face forward #define ML_FULL_FACE_FORWARD (1UL<<1) // full face forward struct ENGINE_API MeshVertex { FLOAT x, y, z; ULONG dummy; // 16 byte alingment }; static inline CTStream &operator>>(CTStream &strm, MeshVertex &mv) { strm>>mv.x; strm>>mv.y; strm>>mv.z; strm>>mv.dummy; return(strm); } static inline CTStream &operator>>(CTStream &strm, const MeshVertex &mv) { strm<<mv.x; strm<<mv.y; strm<<mv.z; strm<<mv.dummy; return(strm); } struct ENGINE_API MeshNormal { FLOAT nx, ny, nz; ULONG dummy; // 16 byte alingment }; static inline CTStream &operator>>(CTStream &strm, MeshNormal &mn) { strm>>mn.nx; strm>>mn.ny; strm>>mn.nz; strm>>mn.dummy; return(strm); } static inline CTStream &operator>>(CTStream &strm, const MeshNormal &mn) { strm<<mn.nx; strm<<mn.ny; strm<<mn.nz; strm<<mn.dummy; return(strm); } struct ENGINE_API MeshUVMap { ULONG muv_iID; CStaticArray<struct MeshTexCoord> muv_aTexCoords; // texture coordinates }; struct ENGINE_API MeshTexCoord { FLOAT u, v; }; static inline CTStream &operator>>(CTStream &strm, MeshTexCoord &mtc) { strm>>mtc.u; strm>>mtc.v; return strm; } static inline CTStream &operator<<(CTStream &strm, const MeshTexCoord &mtc) { strm<<mtc.u; strm<<mtc.v; return strm; } struct ENGINE_API MeshSurface { INDEX msrf_iFirstVertex; INDEX msrf_ctVertices; INDEX msrf_iSurfaceID; CShader *msrf_pShader; ShaderParams msrf_ShadingParams; CStaticArray<struct MeshTriangle> msrf_aTriangles; // list of triangles }; struct ENGINE_API MeshTriangle { INDEX iVertex[3]; }; static inline CTStream &operator>>(CTStream &strm, MeshTriangle &mt) { strm>>mt.iVertex[0]; strm>>mt.iVertex[1]; strm>>mt.iVertex[2]; return strm; } static inline CTStream &operator<<(CTStream &strm, const MeshTriangle &mt) { strm<<mt.iVertex[0]; strm<<mt.iVertex[1]; strm<<mt.iVertex[2]; return strm; } struct ENGINE_API MeshWeightMap { int mwm_iID; CStaticArray<struct MeshVertexWeight> mwm_aVertexWeight; // weight maps }; struct ENGINE_API MeshVertexWeight { INDEX mww_iVertex; // absolute index of the vertex this weight refers to FLOAT mww_fWeight; // weight for this bone [0.0 - 1.0] }; static inline CTStream &operator>>(CTStream &strm, MeshVertexWeight &mww) { strm>>mww.mww_iVertex; // absolute index of the vertex this weight refers to strm>>mww.mww_fWeight; // weight for this bone [0.0 - 1.0] return strm; } static inline CTStream &operator<<(CTStream &strm, const MeshVertexWeight &mww) { strm<<mww.mww_iVertex; // absolute index of the vertex this weight refers to strm<<mww.mww_fWeight; // weight for this bone [0.0 - 1.0] return strm; } struct ENGINE_API MeshMorphMap { INDEX mmp_iID; BOOL mmp_bRelative; CStaticArray<struct MeshVertexMorph> mmp_aMorphMap; // Morph maps }; struct ENGINE_API MeshVertexMorph { INDEX mwm_iVxIndex; // absolute index of the vertex this weight refers to FLOAT mwm_x; FLOAT mwm_y; FLOAT mwm_z; FLOAT mwm_nx; FLOAT mwm_ny; FLOAT mwm_nz; ULONG dummy; // 32 byte padding }; static inline CTStream &operator>>(CTStream &strm, MeshVertexMorph &mwm) { strm>>mwm.mwm_iVxIndex; strm>>mwm.mwm_x; strm>>mwm.mwm_y; strm>>mwm.mwm_z; strm>>mwm.mwm_nx; strm>>mwm.mwm_ny; strm>>mwm.mwm_nz; strm>>mwm.dummy; return(strm); } static inline CTStream &operator>>(CTStream &strm, const MeshVertexMorph &mwm) { strm<<mwm.mwm_iVxIndex; strm<<mwm.mwm_x; strm<<mwm.mwm_y; strm<<mwm.mwm_z; strm<<mwm.mwm_nx; strm<<mwm.mwm_ny; strm<<mwm.mwm_nz; strm<<mwm.dummy; return(strm); } struct ENGINE_API MeshLOD { MeshLOD() { mlod_fMaxDistance = -1; mlod_ulFlags = 0; }; ~MeshLOD() {} FLOAT mlod_fMaxDistance; ULONG mlod_ulFlags; CStaticArray<struct MeshVertex> mlod_aVertices; // vertices CStaticArray<struct MeshNormal> mlod_aNormals; // normals CStaticArray<struct MeshUVMap> mlod_aUVMaps; // UV maps CStaticArray<struct MeshSurface> mlod_aSurfaces; // surfaces CStaticArray<struct MeshWeightMap> mlod_aWeightMaps; // weight maps CStaticArray<struct MeshMorphMap> mlod_aMorphMaps; // morph maps CTString mlod_fnSourceFile;// file name of ascii am file, used in Ska studio }; class ENGINE_API CMesh : public CSerial { public: CMesh(); ~CMesh(); void Optimize(void); void OptimizeLod(MeshLOD &mLod); void NormalizeWeights(void); void NormalizeWeightsInLod(MeshLOD &mlod); void AddMeshLod(MeshLOD &mlod); void RemoveMeshLod(MeshLOD *pmlodRemove); void Read_t( CTStream *istrFile); // throw char * void Write_t( CTStream *ostrFile); // throw char * void Clear(void); SLONG GetUsedMemory(void); CStaticArray<struct MeshLOD> msh_aMeshLODs; }; ENGINE_API void ChangeSurfaceShader_t(MeshSurface &msrf,CTString fnNewShader); #endif /* include-once check. */