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