1 //****************************************************************************//
2 // hardwaremodel.cpp                                                       //
3 // Copyright (C) 2004 Desmecht Laurent                                        //
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 #include "cal3d/error.h"
17 #include "cal3d/hardwaremodel.h"
18 #include "cal3d/coremodel.h"
19 #include "cal3d/model.h"
20 #include "cal3d/coremesh.h"
21 #include "cal3d/bone.h"
22 #include "cal3d/corematerial.h"
23 #include "cal3d/coresubmesh.h"
24 #include "cal3d/coreskeleton.h"
25 #include "cal3d/skeleton.h"
26 
27 
28  /*****************************************************************************/
29 /** Constructs the hardware model instance.
30   *
31   * This function is the default constructor of the hardware model instance.
32   *****************************************************************************/
33 
34 
CalHardwareModel(CalCoreModel * pCoreModel)35 CalHardwareModel::CalHardwareModel(CalCoreModel* pCoreModel)
36 : m_selectedHardwareMesh(-1)
37 {
38   assert(pCoreModel);
39   m_pCoreModel = pCoreModel;
40 
41   m_pVertexBuffer = NULL;
42   m_pIndexBuffer = NULL;
43   m_pNormalBuffer = NULL;
44   m_pWeightBuffer = NULL;
45   m_pMatrixIndexBuffer = NULL;
46   int i;
47   for( i = 0 ; i < 8 ; i++)
48     m_pTextureCoordBuffer[i]=NULL;
49   m_textureCoordNum=0;
50 
51   for( i = 0 ; i < 8 ; i++)
52     m_pTangentSpaceBuffer [i]=NULL;
53 
54   m_totalFaceCount=0;
55   m_totalVertexCount=0;
56 }
57 
58 
59 /*****************************************************************************/
60 /** Set the vertex (position) buffer of the hardware model instance.
61   *
62   * This function set the vertex (position) buffer the hardware model instance.
63   *
64   * @param pVertexBuffer A pointer to the vertex buffer.
65   * @param stride  The number of byte to add to find the next element
66   *
67   *****************************************************************************/
68 
setVertexBuffer(char * pVertexBuffer,int stride)69 void CalHardwareModel::setVertexBuffer( char * pVertexBuffer, int stride)
70 {
71   m_pVertexBuffer = pVertexBuffer;
72   m_vertexStride = stride;
73 }
74 
75  /*****************************************************************************/
76 /** Set the index buffer of the hardware model instance.
77   *
78   * This function set the index buffer the hardware model instance.
79   *
80   * @param pIndexBuffer A pointer to the index buffer.
81   *
82   *****************************************************************************/
83 
setIndexBuffer(CalIndex * pIndexBuffer)84 void CalHardwareModel::setIndexBuffer( CalIndex * pIndexBuffer)
85 {
86   m_pIndexBuffer= pIndexBuffer;
87 }
88 
89  /*****************************************************************************/
90 /** Set the normal buffer of the hardware model instance.
91   *
92   * This function set the normal buffer the hardware model instance.
93   *
94   * @param pNormalBuffer A pointer to the normal buffer.
95   * @param stride  The number of byte to add to find the next element
96   *
97   *****************************************************************************/
98 
setNormalBuffer(char * pNormalBuffer,int stride)99 void CalHardwareModel::setNormalBuffer( char * pNormalBuffer, int stride)
100 {
101   m_pNormalBuffer = pNormalBuffer;
102   m_normalStride = stride;
103 }
104 
105  /*****************************************************************************/
106 /** Set the weight buffer of the hardware model instance.
107   *
108   * This function set the weight buffer the hardware model instance.
109   *
110   * @param pWeightBuffer A pointer to the weight buffer.
111   * @param stride  The number of byte to add to find the next element
112   *
113   *****************************************************************************/
114 
115 
setWeightBuffer(char * pWeightBuffer,int stride)116 void CalHardwareModel::setWeightBuffer( char * pWeightBuffer, int stride)
117 {
118   m_pWeightBuffer = pWeightBuffer;
119   m_weightStride = stride;
120 }
121 
122  /*****************************************************************************/
123 /** Set the matrix index buffer of the hardware model instance.
124   *
125   * This function set the matrix index buffer the hardware model instance.
126   *
127   * @param pMatrixIndexBuffer A pointer to the matrix index buffer.
128   * @param stride  The number of byte to add to find the next element
129   *
130   *****************************************************************************/
131 
132 
setMatrixIndexBuffer(char * pMatrixIndexBuffer,int stride)133 void CalHardwareModel::setMatrixIndexBuffer( char * pMatrixIndexBuffer, int stride)
134 {
135   m_pMatrixIndexBuffer = pMatrixIndexBuffer;
136   m_matrixIndexStride = stride;
137 }
138 
139  /*****************************************************************************/
140 /** Set the number the texture coordinate of the hardware model instance.
141   *
142   * This function set the number the texture coordinate the hardware model instance.
143   *
144   * @param textureCoordNum A integer with the number the texture coordinate.
145   *
146   *****************************************************************************/
147 
setTextureCoordNum(int textureCoordNum)148 void CalHardwareModel::setTextureCoordNum(int textureCoordNum)
149 {
150   if( 0<= textureCoordNum && textureCoordNum < 8)
151   {
152     m_textureCoordNum=textureCoordNum;
153   }
154 }
155 
156  /*****************************************************************************/
157 /** Set the texture coordinate buffer of the hardware model instance.
158   *
159   * This function set the texture coordinate buffer the hardware model instance.
160   *
161   * @param mapId A integer to the texture stage
162   * @param pTextureCoordBuffer A pointer to the texture coord buffer.
163   * @param stride  The number of byte to add to find the next element
164   *
165   *****************************************************************************/
166 
167 
setTextureCoordBuffer(int mapId,char * pTextureCoordBuffer,int stride)168 void CalHardwareModel::setTextureCoordBuffer(int mapId, char * pTextureCoordBuffer, int stride)
169 {
170   if( 0 <= mapId && mapId < 8)
171   {
172     m_pTextureCoordBuffer[mapId] = pTextureCoordBuffer;
173     m_textureCoordStride[mapId] = stride;
174   }
175 }
176 
177  /*****************************************************************************/
178 /** Set the tangent space buffer of the hardware model instance.
179   *
180   * This function set the tangent space buffer the hardware model instance.
181   *
182   * @param mapId A integer to the texture stage
183   * @param pTangentSpaceBuffer A pointer to the tangent space buffer.
184   * @param stride  The number of byte to add to find the next element
185   *
186   *****************************************************************************/
187 
setTangentSpaceBuffer(int mapId,char * pTangentSpaceBuffer,int stride)188 void CalHardwareModel::setTangentSpaceBuffer(int mapId, char * pTangentSpaceBuffer, int stride)
189 {
190   if( 0 <= mapId && mapId < 8)
191   {
192     m_pTangentSpaceBuffer[mapId] = pTangentSpaceBuffer;
193     m_tangentSpaceStride[mapId] = stride;
194   }
195 }
196 
197  /*****************************************************************************/
198 /** Set the list of core mesh ids to use for building the hardware model instance.
199   * setCoreMeshIds must be called before the load method otherwise it will have
200   * no effect. If setCoreMeshIds is not called, the hardware model instance will
201   * use all the core mesh ids from the core model.
202   *
203   * @param coreMeshIds a vector of core mesh ids
204   *
205   *****************************************************************************/
206 
setCoreMeshIds(const std::vector<int> & coreMeshIds)207 void CalHardwareModel::setCoreMeshIds(const std::vector<int>& coreMeshIds)
208 {
209   m_coreMeshIds = coreMeshIds;
210 }
211 
212  /*****************************************************************************/
213 /** Returns the hardware mesh vector.
214   *
215   * This function returns the vector that contains all hardware mesh of the
216   * core mesh instance.
217   *
218   * @return A reference to the hardware mesh vector.
219   *****************************************************************************/
220 
221 
getVectorHardwareMesh()222 std::vector<CalHardwareModel::CalHardwareMesh> & CalHardwareModel::getVectorHardwareMesh()
223 {
224   return m_vectorHardwareMesh;
225 }
226 
227  /*****************************************************************************/
228 /** Provides access to the ambient color.
229   *
230   * This function returns the ambient color of the material of the selected
231   * hardware mesh.
232   *
233   * @param pColorBuffer A pointer to the user-provided buffer where the color
234   *                     data is written to.
235   *****************************************************************************/
236 
237 
getAmbientColor(unsigned char * pColorBuffer)238 void CalHardwareModel::getAmbientColor(unsigned char *pColorBuffer)
239 {
240     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size())
241     && m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial!=0)
242   {
243     CalCoreMaterial::Color& color = m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial->getAmbientColor();
244     pColorBuffer[0] = color.red;
245     pColorBuffer[1] = color.green;
246     pColorBuffer[2] = color.blue;
247     pColorBuffer[3] = color.alpha;
248   }
249   else
250   {
251     pColorBuffer[0] = 0;
252     pColorBuffer[1] = 0;
253     pColorBuffer[2] = 0;
254     pColorBuffer[3] = 0;
255   }
256 }
257 
258  /*****************************************************************************/
259 /** Provides access to the diffuse color.
260   *
261   * This function returns the diffuse color of the material of the selected
262   * hardware mesh.
263   *
264   * @param pColorBuffer A pointer to the user-provided buffer where the color
265   *                     data is written to.
266   *****************************************************************************/
267 
268 
getDiffuseColor(unsigned char * pColorBuffer)269 void CalHardwareModel::getDiffuseColor(unsigned char *pColorBuffer)
270 {
271     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size())
272     && m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial!=0)
273   {
274     CalCoreMaterial::Color& color = m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial->getDiffuseColor();
275     pColorBuffer[0] = color.red;
276     pColorBuffer[1] = color.green;
277     pColorBuffer[2] = color.blue;
278     pColorBuffer[3] = color.alpha;
279   }
280   else
281   {
282     pColorBuffer[0] = 0;
283     pColorBuffer[1] = 0;
284     pColorBuffer[2] = 0;
285     pColorBuffer[3] = 0;
286   }
287 }
288 
289 /*****************************************************************************/
290 /** Provides access to the specular color.
291   *
292   * This function returns the specular color of the material of the selected
293   * hardware.
294   *
295   * @param pColorBuffer A pointer to the user-provided buffer where the color
296   *                     data is written to.
297   *****************************************************************************/
298 
getSpecularColor(unsigned char * pColorBuffer)299 void CalHardwareModel::getSpecularColor(unsigned char *pColorBuffer)
300 {
301     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size())
302     && m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial!=0)
303   {
304     CalCoreMaterial::Color& color = m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial->getSpecularColor();
305     pColorBuffer[0] = color.red;
306     pColorBuffer[1] = color.green;
307     pColorBuffer[2] = color.blue;
308     pColorBuffer[3] = color.alpha;
309   }
310   else
311   {
312     pColorBuffer[0] = 0;
313     pColorBuffer[1] = 0;
314     pColorBuffer[2] = 0;
315     pColorBuffer[3] = 0;
316   }
317 }
318 
319 /*****************************************************************************/
320 /** Returns the shininess factor.
321   *
322   * This function returns the shininess factor of the material of the selected
323   * hardware mesh..
324   *
325   * @return The shininess factor.
326   *****************************************************************************/
327 
328 
getShininess() const329 float CalHardwareModel::getShininess() const
330 {
331     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size())
332     && m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial!=0)
333   {
334     return m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial->getShininess();
335   }
336   else
337   {
338     return 50.0f;
339   }
340 }
341 
342  /*****************************************************************************/
343 /** Returns the bone space rotation of the bone boneId.
344   *
345   * This function returns the rotation to bring a point into the
346   *bone instance space of the bone boneId of the selected hardware mesh.
347   *
348   * @param boneId A integer with the bone number
349   * @return The rotation to bring a point into bone space.
350   *****************************************************************************/
351 
getRotationBoneSpace(int boneId,CalSkeleton * pSkeleton)352 const CalQuaternion & CalHardwareModel::getRotationBoneSpace(int boneId, CalSkeleton *pSkeleton)
353 {
354   const std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone();
355   return vectorBone[m_vectorHardwareMesh[m_selectedHardwareMesh].m_vectorBonesIndices[boneId]]->getRotationBoneSpace();
356 }
357 
358  /*****************************************************************************/
359 /** Returns the bone space translation of the bone boneId.
360   *
361   * This function returns the translation to bring a point into the
362   *bone instance space of the bone boneId of the selected hardware mesh.
363   *
364   * @param boneId A integer with the bone number
365   * @return The translation to bring a point into bone space.
366   *****************************************************************************/
367 
368 
getTranslationBoneSpace(int boneId,CalSkeleton * pSkeleton)369 const CalVector & CalHardwareModel::getTranslationBoneSpace(int boneId, CalSkeleton *pSkeleton)
370 {
371   const std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone();
372   return vectorBone[m_vectorHardwareMesh[m_selectedHardwareMesh].m_vectorBonesIndices[boneId]]->getTranslationBoneSpace();
373 }
374 
375  /*****************************************************************************/
376 /** Returns the number of hardware meshes.
377   *
378   * This function returns the number of hardware meshes in the hardware model
379   * instance.
380   *
381   * @return The number of hardware meshes.
382   *****************************************************************************/
383 
384 
385 
getHardwareMeshCount() const386 int CalHardwareModel::getHardwareMeshCount() const
387 {
388   return m_vectorHardwareMesh.size();
389 }
390 
391  /*****************************************************************************/
392 /** Returns the number of faces.
393   *
394   * This function returns the number of faces in the selected hardware mesh instance.
395   *
396   * @return The number of faces.
397   *****************************************************************************/
398 
399 
getFaceCount() const400 int CalHardwareModel::getFaceCount() const
401 {
402     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
403   {
404     return m_vectorHardwareMesh[m_selectedHardwareMesh].faceCount;
405   }
406   return 0;
407 }
408 
409 /*****************************************************************************/
410 /** Returns the number of vertex.
411   *
412   * This function returns the number of vertex in the selected hardware mesh instance.
413   *
414   * @return The number of vertex.
415   *****************************************************************************/
416 
getVertexCount() const417 int CalHardwareModel::getVertexCount() const
418 {
419     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
420   {
421     return m_vectorHardwareMesh[m_selectedHardwareMesh].vertexCount;
422   }
423   return 0;
424 }
425 
426 /*****************************************************************************/
427 /** Returns the number of bone.
428   *
429   * This function returns the number of bone in the selected hardware mesh instance.
430   *
431   * @return The number of bone.
432   *****************************************************************************/
433 
434 
getBoneCount() const435 int CalHardwareModel::getBoneCount() const
436 {
437     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
438   {
439     return m_vectorHardwareMesh[m_selectedHardwareMesh].m_vectorBonesIndices.size();
440   }
441   return 0;
442 }
443 
444 /*****************************************************************************/
445 /** Returns the base vertex index.
446   *
447   * This function returns the base vertex index of the selected hardware mesh instance.
448   *
449   * @return a integer with the base vertex index.
450   *****************************************************************************/
451 
452 
getBaseVertexIndex() const453 int CalHardwareModel::getBaseVertexIndex() const
454 {
455     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
456   {
457     return m_vectorHardwareMesh[m_selectedHardwareMesh].baseVertexIndex;
458   }
459   return 0;
460 }
461 
462 /*****************************************************************************/
463 /** Returns the start index.
464   *
465   * This function returns the start index of the selected hardware mesh instance.
466   *
467   * @return a integer with the start index.
468   *****************************************************************************/
469 
470 
getStartIndex() const471 int CalHardwareModel::getStartIndex() const
472 {
473     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
474   {
475     return m_vectorHardwareMesh[m_selectedHardwareMesh].startIndex;
476   }
477   return 0;
478 }
479 
480 
481  /*****************************************************************************/
482 /** Selects a hardware mesh for rendering data queries.
483   *
484   * This function selects a hardware mesh for further rendering data queries.
485   *
486   * @param meshId The ID of the hardware mesh that should be used for further rendering
487   *               data queries.
488   *
489   * @return One of the following values:
490   *         \li \b true if successful
491   *         \li \b false if an error happend
492   *****************************************************************************/
493 
494 
selectHardwareMesh(size_t meshId)495 bool CalHardwareModel::selectHardwareMesh(size_t meshId)
496 {
497   if( meshId < m_vectorHardwareMesh.size())
498   {
499     m_selectedHardwareMesh=meshId;
500     return true;
501   }
502   return false;
503 }
504 
505 /*****************************************************************************/
506 /** Returns the number of faces in the hardware model instance.
507   *
508   * This function returns the number of faces in the hardware model instance.
509   *
510   * @return The number of faces.
511   *****************************************************************************/
512 
513 
getTotalFaceCount() const514 int CalHardwareModel::getTotalFaceCount() const
515 {
516   return m_totalFaceCount;
517 }
518 
519 /*****************************************************************************/
520 /** Returns the number of vertices in the hardware model instance.
521   *
522   * This function returns the number of vertices in the hardware model instance.
523   *
524   * @return The number of vertices.
525   *****************************************************************************/
526 
527 
getTotalVertexCount() const528 int CalHardwareModel::getTotalVertexCount() const
529 {
530   return m_totalVertexCount;
531 }
532 
533 
534 /*****************************************************************************/
535 /** Provides access to a specified map user data.
536 *
537 * This function returns the user data stored in the specified map of the
538 * material of the selected hardware mesh.
539 *
540 * @param mapId The ID of the map.
541 *
542 * @return One of the following values:
543 *         \li the user data stored in the specified map
544 *         \li \b 0 if an error happend
545 *****************************************************************************/
546 
getMapUserData(int mapId)547 Cal::UserData CalHardwareModel::getMapUserData(int mapId)
548 {
549     if( m_selectedHardwareMesh >= 0 && m_selectedHardwareMesh < int(m_vectorHardwareMesh.size()))
550   {
551     if(m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial==0)
552       return 0;
553 
554     // get the map vector
555         std::vector<CalCoreMaterial::Map>& vectorMap = m_vectorHardwareMesh[m_selectedHardwareMesh].pCoreMaterial->getVectorMap();
556 
557 
558         // check if the map id is valid
559         if((mapId < 0) || (mapId >= (int)vectorMap.size()))
560         {
561       CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
562       return 0;
563         }
564 
565         return vectorMap[mapId].userData;
566   }
567   return 0;
568 }
569 
570 /*****************************************************************************/
571 /** Compute the information needed to use the hardware model .
572 *
573 * This function Compute the information needed to use the hardware model,
574 * it fill vertex buffers with the model data
575 *
576 * @param baseVertexIndex The base vertex Index.
577 * @param startIndex The start index.
578 * @param maxBonesPerMesh The maximun of bone by hardware mesh
579 *
580 * @return One of the following values:
581 *         \li \b true if succeed
582 *         \li \b false if an error happend
583 *****************************************************************************/
584 
585 
586 
load(int baseVertexIndex,int startIndex,int maxBonesPerMesh)587 bool CalHardwareModel::load(int baseVertexIndex, int startIndex,int maxBonesPerMesh)
588 {
589   if(m_pVertexBuffer==NULL ||  m_pNormalBuffer ==NULL|| m_pWeightBuffer ==NULL || m_pMatrixIndexBuffer ==NULL)
590   {
591     CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
592     return false;
593   }
594 
595   int mapId;
596   for(mapId = 0; mapId < m_textureCoordNum; mapId++)
597   {
598     if(m_pTextureCoordBuffer[mapId]==NULL)
599     {
600       CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
601       return false;
602     }
603   }
604 
605   m_vectorVertexIndiceUsed.resize(50000);
606   int vertexCount=baseVertexIndex;
607   int faceIndexCount = startIndex;
608 
609         // unused.
610   //CalCoreSkeleton * pCoreSkeleton = m_pCoreModel->getCoreSkeleton();
611   //std::vector< CalCoreBone *>& vectorBone = pCoreSkeleton->getVectorCoreBone();
612 
613   // if unspecified, fill with all core mesh ids
614   if(m_coreMeshIds.empty())
615   {
616     for(int coreMeshId = 0; coreMeshId < m_pCoreModel->getCoreMeshCount(); coreMeshId++)
617       m_coreMeshIds.push_back(coreMeshId);
618   }
619 
620   for(std::vector<int>::iterator meshIdIt = m_coreMeshIds.begin();meshIdIt != m_coreMeshIds.end(); meshIdIt++)
621   {
622     int meshId = *meshIdIt;
623     CalCoreMesh *pCoreMesh = m_pCoreModel->getCoreMesh(meshId);
624     int submeshCount= pCoreMesh->getCoreSubmeshCount();
625     int submeshId;
626     for(submeshId = 0 ;submeshId < submeshCount ; submeshId++)
627     {
628       CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId);
629 
630       std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex();
631       std::vector<CalCoreSubmesh::Face>& vectorFace = pCoreSubmesh->getVectorFace();
632                         // unused.
633       //std::vector< std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorTex = pCoreSubmesh->getVectorVectorTextureCoordinate();
634 
635       CalHardwareMesh hardwareMesh;
636 
637       hardwareMesh.meshId = meshId;
638       hardwareMesh.submeshId = submeshId;
639 
640       hardwareMesh.baseVertexIndex=vertexCount;
641       hardwareMesh.startIndex=faceIndexCount;
642       hardwareMesh.m_vectorBonesIndices.clear();
643 
644       hardwareMesh.vertexCount=0;
645       hardwareMesh.faceCount=0;
646 
647       int startIndex=hardwareMesh.startIndex;
648 
649       int faceId;
650       for( faceId =0 ;faceId<pCoreSubmesh->getFaceCount();faceId++)
651       {
652         if(canAddFace(hardwareMesh,vectorFace[faceId],vectorVertex,maxBonesPerMesh))
653         {
654           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
655           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
656           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
657           hardwareMesh.faceCount++;
658         }
659         else
660         {
661           vertexCount+=hardwareMesh.vertexCount;
662           faceIndexCount+=hardwareMesh.faceCount*3;
663           hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
664 
665           m_vectorHardwareMesh.push_back(hardwareMesh);
666 
667           hardwareMesh.baseVertexIndex=vertexCount;
668           hardwareMesh.startIndex=faceIndexCount;
669 
670           hardwareMesh.m_vectorBonesIndices.clear();
671           hardwareMesh.vertexCount=0;
672           hardwareMesh.faceCount=0;
673 
674           startIndex=hardwareMesh.startIndex;
675 
676           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]=   addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh);
677           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh);
678           m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh);
679           hardwareMesh.faceCount++;
680         }
681       }
682 
683       vertexCount+=hardwareMesh.vertexCount;
684       faceIndexCount+=hardwareMesh.faceCount*3;
685       hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId());
686 
687       m_vectorHardwareMesh.push_back(hardwareMesh);
688 
689     }
690   }
691 
692     m_vectorVertexIndiceUsed.clear();
693 
694 
695   m_totalFaceCount=0;
696   m_totalVertexCount=0;
697 
698   for(size_t hardwareMeshId = 0; hardwareMeshId <  m_vectorHardwareMesh.size(); hardwareMeshId++)
699   {
700     m_totalFaceCount+=m_vectorHardwareMesh[hardwareMeshId].faceCount;
701     m_totalVertexCount+=m_vectorHardwareMesh[hardwareMeshId].vertexCount;
702   }
703 
704 
705     return true;
706 }
707 
708 
709 
canAddFace(CalHardwareMesh & hardwareMesh,CalCoreSubmesh::Face & face,std::vector<CalCoreSubmesh::Vertex> & vectorVertex,int maxBonesPerMesh)710 bool CalHardwareModel::canAddFace(CalHardwareMesh &hardwareMesh, CalCoreSubmesh::Face & face,std::vector<CalCoreSubmesh::Vertex>& vectorVertex, int maxBonesPerMesh)
711 {
712   size_t boneCount=hardwareMesh.m_vectorBonesIndices.size();
713 
714   for(unsigned faceIndex=0;faceIndex<3;faceIndex++)
715   {
716     for(size_t influenceIndex=0;influenceIndex< vectorVertex[face.vertexId[faceIndex]].vectorInfluence.size();influenceIndex++)
717     {
718       unsigned boneIndex=0;
719       while(boneIndex< hardwareMesh.m_vectorBonesIndices.size()
720         && hardwareMesh.m_vectorBonesIndices[boneIndex]!=vectorVertex[face.vertexId[faceIndex]].vectorInfluence[influenceIndex].boneId)
721         boneIndex++;
722 
723       if(boneIndex==hardwareMesh.m_vectorBonesIndices.size())
724         boneCount++;
725     }
726   }
727 
728   /// @todo Change maxBonesPerMesh to a size_t?
729         if(int(boneCount)>maxBonesPerMesh)
730     return false;
731 
732   return true;
733 }
734 
735 
736 
addVertex(CalHardwareMesh & hardwareMesh,int indice,CalCoreSubmesh * pCoreSubmesh,int maxBonesPerMesh)737 int CalHardwareModel::addVertex(CalHardwareMesh &hardwareMesh, int indice, CalCoreSubmesh *pCoreSubmesh, int maxBonesPerMesh)
738 {
739   int i=0;
740 
741   while(i< hardwareMesh.vertexCount && m_vectorVertexIndiceUsed[i]!=indice)
742     i++;
743 
744   if(i != hardwareMesh.vertexCount)
745     return i;
746 
747 
748   std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex();
749   std::vector< std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorvectorTextureCoordinate = pCoreSubmesh->getVectorVectorTextureCoordinate();
750   std::vector< std::vector<CalCoreSubmesh::TangentSpace> >& vectorvectorTangentSpace = pCoreSubmesh->getVectorVectorTangentSpace();
751 
752   m_vectorVertexIndiceUsed[hardwareMesh.vertexCount]=indice;
753 
754   memcpy(&m_pVertexBuffer[(hardwareMesh.baseVertexIndex+i)*m_vertexStride],&vectorVertex[indice].position,sizeof(CalVector));
755 
756   memcpy(&m_pNormalBuffer[(hardwareMesh.baseVertexIndex+i)*m_normalStride],&vectorVertex[indice].normal,sizeof(CalVector));
757 
758   /// @todo change m_textureCoordName to size_t?
759   size_t mapId;
760   for(mapId = 0; int(mapId) < m_textureCoordNum; mapId++)
761   {
762     if( vectorvectorTextureCoordinate.size() > mapId)
763       memcpy(&m_pTextureCoordBuffer[mapId][(hardwareMesh.baseVertexIndex+i)*m_textureCoordStride[mapId]],&vectorvectorTextureCoordinate[mapId][indice],sizeof(CalCoreSubmesh::TextureCoordinate));
764     else
765       memset(&m_pTextureCoordBuffer[mapId][(hardwareMesh.baseVertexIndex+i)*m_textureCoordStride[mapId]],0,sizeof(CalCoreSubmesh::TextureCoordinate));
766 
767   }
768 
769   for(mapId = 0; mapId < 8 ; mapId++)
770   {
771     if(m_pTangentSpaceBuffer[mapId] != NULL)
772     {
773       if(vectorvectorTangentSpace.size() > mapId && pCoreSubmesh->isTangentsEnabled(mapId))
774         memcpy(&m_pTangentSpaceBuffer[mapId][(hardwareMesh.baseVertexIndex+i)*m_tangentSpaceStride[mapId]],&vectorvectorTangentSpace[mapId][indice],sizeof(CalCoreSubmesh::TangentSpace));
775       else
776         memset(&m_pTangentSpaceBuffer[mapId][(hardwareMesh.baseVertexIndex+i)*m_tangentSpaceStride[mapId]],0,sizeof(CalCoreSubmesh::TangentSpace));
777     }
778   }
779 
780   for(size_t l=0 ; l<4 ; l++)
781   {
782     if(l < vectorVertex[indice].vectorInfluence.size())
783     {
784       int BoneId = vectorVertex[indice].vectorInfluence[l].boneId;
785 
786       float newBoneId = (float)addBoneIndice(hardwareMesh,BoneId,maxBonesPerMesh);
787 
788       memcpy(&m_pWeightBuffer[(hardwareMesh.baseVertexIndex+i)*m_weightStride+l * sizeof(float) ], &vectorVertex[indice].vectorInfluence[l].weight ,sizeof(float));
789       memcpy(&m_pMatrixIndexBuffer[(hardwareMesh.baseVertexIndex+i)*m_matrixIndexStride+l * sizeof(float) ], &newBoneId ,sizeof(float));
790     }
791     else
792     {
793       memset(&m_pWeightBuffer[(hardwareMesh.baseVertexIndex+i)*m_weightStride+l * sizeof(float) ], 0 ,sizeof(float));
794       memset(&m_pMatrixIndexBuffer[(hardwareMesh.baseVertexIndex+i)*m_matrixIndexStride+l * sizeof(float) ], 0 ,sizeof(float));
795     }
796   }
797 
798   hardwareMesh.vertexCount++;
799   return i;
800 }
801 
802 
addBoneIndice(CalHardwareMesh & hardwareMesh,int Indice,int maxBonesPerMesh)803 int CalHardwareModel::addBoneIndice(CalHardwareMesh &hardwareMesh, int Indice, int maxBonesPerMesh)
804 {
805   size_t i=0;
806   while(i< hardwareMesh.m_vectorBonesIndices.size()  && hardwareMesh.m_vectorBonesIndices[i]!=Indice)
807     i++;
808 
809   if( i != hardwareMesh.m_vectorBonesIndices.size())
810     return i;
811 
812   /// @todo change maxBonesPerMesh to size_t?
813         if(int(hardwareMesh.m_vectorBonesIndices.size())<maxBonesPerMesh)
814   {
815     hardwareMesh.m_vectorBonesIndices.push_back(Indice);
816     return i;
817   }
818   else
819   {
820     return -1;
821   }
822 }
823