1 //****************************************************************************//
2 // coremesh.cpp                                                               //
3 // Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger                       //
4 //****************************************************************************//
5 // This library is free software; you can redistribute it and/or modify it    //
6 // under the terms of the GNU Lesser General Public License as published by   //
7 // the Free Software Foundation; either version 2.1 of the License, or (at    //
8 // your option) any later version.                                            //
9 //****************************************************************************//
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 //****************************************************************************//
16 // Includes                                                                   //
17 //****************************************************************************//
18 
19 #include "cal3d/coremesh.h"
20 #include "cal3d/error.h"
21 #include "cal3d/coresubmesh.h"
22 #include "cal3d/coresubmorphtarget.h"
23 
24  /*****************************************************************************/
25 /** Constructs the core mesh instance.
26   *
27   * This function is the default constructor of the core mesh instance.
28   *****************************************************************************/
29 
CalCoreMesh()30 CalCoreMesh::CalCoreMesh()
31 {
32 }
33 
34  /*****************************************************************************/
35 /** Destructs the core mesh instance.
36   *
37   * This function is the destructor of the core mesh instance.
38   *****************************************************************************/
39 
~CalCoreMesh()40 CalCoreMesh::~CalCoreMesh()
41 {
42   // destroy all core submeshes
43   for(size_t i = 0; i < m_vectorCoreSubmesh.size(); ++i)
44   {
45     delete m_vectorCoreSubmesh[i];
46   }
47 
48   m_vectorCoreSubmesh.clear();
49 }
50 
51  /*****************************************************************************/
52 /** Adds a core submesh.
53   *
54   * This function adds a core submesh to the core mesh instance.
55   *
56   * @param pCoreSubmesh A pointer to the core submesh that should be added.
57   *
58   * @return One of the following values:
59   *         \li the assigned submesh \b ID of the added core submesh
60   *         \li \b -1 if an error happend
61   *****************************************************************************/
62 
addCoreSubmesh(CalCoreSubmesh * pCoreSubmesh)63 int CalCoreMesh::addCoreSubmesh(CalCoreSubmesh *pCoreSubmesh)
64 {
65   // get next bone id
66   int submeshId;
67   submeshId = m_vectorCoreSubmesh.size();
68 
69   m_vectorCoreSubmesh.push_back(pCoreSubmesh);
70 
71   return submeshId;
72 }
73 
74 
75  /*****************************************************************************/
76 /** Provides access to a core submesh.
77   *
78   * This function returns the core submesh with the given ID.
79   *
80   * @param id The ID of the core submesh that should be returned.
81   *
82   * @return One of the following values:
83   *         \li a pointer to the core submesh
84   *         \li \b 0 if an error happend
85   *****************************************************************************/
86 
getCoreSubmesh(int id)87 CalCoreSubmesh *CalCoreMesh::getCoreSubmesh(int id)
88 {
89   if((id < 0) || (id >= (int)m_vectorCoreSubmesh.size()))
90   {
91     CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
92     return 0;
93   }
94 
95   return m_vectorCoreSubmesh[id];
96 }
97 
98  /*****************************************************************************/
99 /** Returns the number of core submeshes.
100   *
101   * This function returns the number of core submeshes in the core mesh
102   * instance.
103   *
104   * @return The number of core submeshes.
105   *****************************************************************************/
106 
getCoreSubmeshCount() const107 int CalCoreMesh::getCoreSubmeshCount() const
108 {
109   return m_vectorCoreSubmesh.size();
110 }
111 
112  /*****************************************************************************/
113 /** Returns the core submesh vector.
114   *
115   * This function returns the vector that contains all core submeshes of the
116   * core mesh instance.
117   *
118   * @return A reference to the core submesh vector.
119   *****************************************************************************/
120 
getVectorCoreSubmesh()121 std::vector<CalCoreSubmesh *>& CalCoreMesh::getVectorCoreSubmesh()
122 {
123   return m_vectorCoreSubmesh;
124 }
125 
126  /*****************************************************************************/
127 /** Adds a core submesh.
128   *
129   * This function adds a core mesh as a blend target.
130   * It adds appropriate CalCoreSubMorphTargets to each of the core sub meshes.
131   *
132   * @param pCoreMesh A pointer to the core mesh that shoulb become a blend target.
133   *
134   * @return One of the following values:
135   *         \li the assigned morph target \b ID of the added blend target
136   *         \li \b -1 if an error happend
137   *****************************************************************************/
138 
addAsMorphTarget(CalCoreMesh * pCoreMesh)139 int CalCoreMesh::addAsMorphTarget(CalCoreMesh *pCoreMesh)
140 {
141   //Check if the numbers of vertices allow a blending
142   std::vector<CalCoreSubmesh *>& otherVectorCoreSubmesh = pCoreMesh->getVectorCoreSubmesh();
143   if (m_vectorCoreSubmesh.size() != otherVectorCoreSubmesh.size())
144   {
145     CalError::setLastError(CalError::INTERNAL, __FILE__, __LINE__);
146     return -1;
147   }
148   if (m_vectorCoreSubmesh.size() == 0)
149   {
150     CalError::setLastError(CalError::INTERNAL, __FILE__, __LINE__);
151     return -1;
152   }
153   std::vector<CalCoreSubmesh *>::iterator iteratorCoreSubmesh = m_vectorCoreSubmesh.begin();
154   std::vector<CalCoreSubmesh *>::iterator otherIteratorCoreSubmesh = otherVectorCoreSubmesh.begin();
155   int subMorphTargetID = (*iteratorCoreSubmesh)->getCoreSubMorphTargetCount();
156   while(iteratorCoreSubmesh != m_vectorCoreSubmesh.end())
157   {
158     if((*iteratorCoreSubmesh)->getVertexCount() != (*otherIteratorCoreSubmesh)->getVertexCount())
159     {
160       CalError::setLastError(CalError::INTERNAL, __FILE__, __LINE__);
161       return -1;
162     }
163     ++iteratorCoreSubmesh;
164     ++otherIteratorCoreSubmesh;
165   }
166   //Adding the blend targets to each of the core sub meshes
167   iteratorCoreSubmesh = m_vectorCoreSubmesh.begin();
168   otherIteratorCoreSubmesh = otherVectorCoreSubmesh.begin();
169   while(iteratorCoreSubmesh != m_vectorCoreSubmesh.end())
170   {
171     int vertexCount = (*otherIteratorCoreSubmesh)->getVertexCount();
172     CalCoreSubMorphTarget *pCalCoreSubMorphTarget = new CalCoreSubMorphTarget();
173     if(!pCalCoreSubMorphTarget->reserve(vertexCount)) return -1;
174     std::vector<CalCoreSubmesh::Vertex>& vectorVertex = (*otherIteratorCoreSubmesh)->getVectorVertex();
175     std::vector<CalCoreSubmesh::Vertex>::iterator iteratorVectorVertex = vectorVertex.begin();
176     for(int i = 0;i<vertexCount;++i)
177     {
178       CalCoreSubMorphTarget::BlendVertex blendVertex;
179       blendVertex.position = (*iteratorVectorVertex).position;
180       blendVertex.normal = (*iteratorVectorVertex).normal;
181       if(!pCalCoreSubMorphTarget->setBlendVertex(i,blendVertex)) return -1;
182       ++iteratorVectorVertex;
183     }
184     (*iteratorCoreSubmesh)->addCoreSubMorphTarget(pCalCoreSubMorphTarget);
185     ++iteratorCoreSubmesh;
186     ++otherIteratorCoreSubmesh;
187   }
188   return subMorphTargetID;
189 }
190 
191  /*****************************************************************************/
192 /** Scale the Mesh.
193   *
194   * This function rescale all the data that are in the core mesh instance.
195   *
196   * @param factor A float with the scale factor
197   *
198   *****************************************************************************/
199 
200 
scale(float factor)201 void CalCoreMesh::scale(float factor)
202 {
203 	std::vector<CalCoreSubmesh *>::iterator iteratorCoreSubmesh;
204 	for(iteratorCoreSubmesh = m_vectorCoreSubmesh.begin(); iteratorCoreSubmesh != m_vectorCoreSubmesh.end(); ++iteratorCoreSubmesh)
205 	{
206 		(*iteratorCoreSubmesh)->scale(factor);
207 	}
208 }
209 
210  /*****************************************************************************/
211 /**
212   * Set the name of the file in which the core mesh is stored, if any.
213   *
214   * @param filename The path of the file.
215   *****************************************************************************/
216 
setFilename(const std::string & filename)217 void CalCoreMesh::setFilename(const std::string& filename)
218 {
219   m_filename = filename;
220 }
221 
222  /*****************************************************************************/
223 /**
224   * Get the name of the file in which the core mesh is stored, if any.
225   *
226   * @return One of the following values:
227   *         \li \b empty string if the mesh was not stored in a file
228   *         \li \b the path of the file
229   *
230   *****************************************************************************/
231 
getFilename(void) const232 const std::string& CalCoreMesh::getFilename(void) const
233 {
234   return m_filename;
235 }
236 
237  /*****************************************************************************/
238 /**
239   * Set the symbolic name of the core mesh.
240   *
241   * @param name A symbolic name.
242   *****************************************************************************/
243 
setName(const std::string & name)244 void CalCoreMesh::setName(const std::string& name)
245 {
246   m_name = name;
247 }
248 
249  /*****************************************************************************/
250 /**
251   * Get the symbolic name the core mesh.
252   *
253   * @return One of the following values:
254   *         \li \b empty string if the mesh was no associated to a symbolic name
255   *         \li \b the symbolic name
256   *
257   *****************************************************************************/
258 
getName(void) const259 const std::string& CalCoreMesh::getName(void) const
260 {
261   return m_name;
262 }
263