shdsubmesh.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWShade *
  23. * *
  24. * $Archive:: wwshade/shdsubmesh.cpp $*
  25. * *
  26. * Org Author:: Jani P *
  27. * *
  28. * Author : Kenny Mitchell *
  29. * *
  30. * $Modtime:: 07/12/02 10:31a $*
  31. * *
  32. * $Revision:: 1 $*
  33. * *
  34. * 07/12/02 KM Removed legacy mesh conversion *
  35. *---------------------------------------------------------------------------------------------*
  36. *---------------------------------------------------------------------------------------------*/
  37. #include "shddefmanager.h"
  38. #include "shdsubmesh.h"
  39. #include "shdrenderer.h"
  40. #include "shdlegacyw3d.h"
  41. #include "shdclassids.h"
  42. #include "chunkio.h"
  43. #include "texture.h"
  44. #include "w3d_file.h"
  45. #include "ww3d.h"
  46. #include "dx8fvf.h"
  47. #include "dx8wrapper.h"
  48. #include "meshmdl.h"
  49. #include "texture.h"
  50. #include "aabtree.h"
  51. #include "sharebuf.h"
  52. ShdSubMeshClass::ShdSubMeshClass(void)
  53. :
  54. Shader(NULL),
  55. S(NULL),
  56. T(NULL),
  57. SxT(NULL),
  58. Diffuse(NULL),
  59. FirstVisiblePolygon(0),
  60. VisiblePolygonCount(0),
  61. Sorting(false)
  62. {
  63. for (int i=0;i<MAX_TEXTURE_STAGES;++i)
  64. {
  65. UV[i]=NULL;
  66. }
  67. }
  68. ShdSubMeshClass::ShdSubMeshClass(const ShdSubMeshClass& that)
  69. :
  70. Shader(NULL),
  71. S(NULL),
  72. T(NULL),
  73. SxT(NULL),
  74. Diffuse(NULL),
  75. FirstVisiblePolygon(that.FirstVisiblePolygon),
  76. VisiblePolygonCount(that.VisiblePolygonCount),
  77. Sorting(false)
  78. {
  79. for (int i=0;i<MAX_TEXTURE_STAGES;++i)
  80. {
  81. UV[i]=NULL;
  82. }
  83. *this = that;
  84. }
  85. ShdSubMeshClass & ShdSubMeshClass::operator = (const ShdSubMeshClass & that)
  86. {
  87. if (this != &that)
  88. {
  89. FirstVisiblePolygon=that.FirstVisiblePolygon;
  90. VisiblePolygonCount=that.VisiblePolygonCount;
  91. Sorting=that.Sorting;
  92. REF_PTR_SET(Shader,that.Shader);
  93. for (int i=0;i<MAX_TEXTURE_STAGES;++i)
  94. {
  95. REF_PTR_SET(UV[i],that.UV[i]);
  96. }
  97. REF_PTR_SET(S,that.S);
  98. REF_PTR_SET(T,that.T);
  99. REF_PTR_SET(SxT,that.SxT);
  100. REF_PTR_SET(Diffuse,that.Diffuse);
  101. MeshGeometryClass::operator =(that);
  102. }
  103. return * this;
  104. }
  105. ShdSubMeshClass::~ShdSubMeshClass(void)
  106. {
  107. REF_PTR_RELEASE(Shader);
  108. for (int i=0;i<MAX_TEXTURE_STAGES;++i)
  109. {
  110. REF_PTR_RELEASE(UV[i]);
  111. }
  112. REF_PTR_RELEASE(S);
  113. REF_PTR_RELEASE(T);
  114. REF_PTR_RELEASE(SxT);
  115. REF_PTR_RELEASE(Diffuse);
  116. }
  117. // The legacy renderer is FVF-based so we need to figure out what FVF format to use
  118. static unsigned Define_FVF(MeshModelClass* mmc,bool enable_lighting)
  119. {
  120. if (mmc->Get_Flag(MeshGeometryClass::SKIN)) {
  121. return dynamic_fvf_type;
  122. }
  123. if ((!!mmc->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) {
  124. return dynamic_fvf_type;
  125. }
  126. unsigned fvf=D3DFVF_XYZ;
  127. int tex_coord_count=mmc->Get_UV_Array_Count();
  128. if (mmc->Get_Color_Array(0,false)) {
  129. fvf|=D3DFVF_DIFFUSE;
  130. }
  131. if (mmc->Get_Color_Array(1,false)) {
  132. fvf|=D3DFVF_SPECULAR;
  133. }
  134. switch (tex_coord_count) {
  135. default:
  136. case 0:
  137. break;
  138. case 1: fvf|=D3DFVF_TEX1; break;
  139. case 2: fvf|=D3DFVF_TEX2; break;
  140. case 3: fvf|=D3DFVF_TEX3; break;
  141. case 4: fvf|=D3DFVF_TEX4; break;
  142. case 5: fvf|=D3DFVF_TEX5; break;
  143. case 6: fvf|=D3DFVF_TEX6; break;
  144. case 7: fvf|=D3DFVF_TEX7; break;
  145. case 8: fvf|=D3DFVF_TEX8; break;
  146. }
  147. if (!mmc->Needs_Vertex_Normals()) { //enable_lighting || mmc->Get_Flag(MeshModelClass::PRELIT_MASK)) {
  148. return fvf;
  149. }
  150. fvf|=D3DFVF_NORMAL; // Realtime-lit
  151. return fvf;
  152. }
  153. // The legacy renderer is FVF-based so we need to figure out what FVF format to use
  154. static unsigned Define_FVF(ShdSubMeshClass* ssm,bool enable_lighting)
  155. {
  156. if (ssm->Get_Flag(MeshGeometryClass::SKIN)) {
  157. return dynamic_fvf_type;
  158. }
  159. if ((!!ssm->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) {
  160. return dynamic_fvf_type;
  161. }
  162. unsigned fvf=D3DFVF_XYZ;
  163. int tex_coord_count=0;
  164. for (tex_coord_count=0;tex_coord_count < MeshMatDescClass::MAX_TEX_STAGES; tex_coord_count++) {
  165. if (ssm->Get_UV_Array(tex_coord_count) == NULL) {
  166. break;
  167. }
  168. }
  169. if (ssm->Get_Diffuse_Array() != NULL) {
  170. fvf|=D3DFVF_DIFFUSE;
  171. }
  172. switch (tex_coord_count) {
  173. default:
  174. case 0:
  175. break;
  176. case 1: fvf|=D3DFVF_TEX1; break;
  177. case 2: fvf|=D3DFVF_TEX2; break;
  178. case 3: fvf|=D3DFVF_TEX3; break;
  179. case 4: fvf|=D3DFVF_TEX4; break;
  180. case 5: fvf|=D3DFVF_TEX5; break;
  181. case 6: fvf|=D3DFVF_TEX6; break;
  182. case 7: fvf|=D3DFVF_TEX7; break;
  183. case 8: fvf|=D3DFVF_TEX8; break;
  184. }
  185. if (ssm->Get_Vertex_Normal_Array() != NULL) {
  186. fvf|=D3DFVF_NORMAL; // Realtime-lit
  187. }
  188. return fvf;
  189. }
  190. void ShdSubMeshClass::Init_From_Legacy_Mesh_Model(MeshModelClass* model,int first_polygon)
  191. {
  192. WWASSERT(first_polygon<model->Get_Polygon_Count());
  193. Sorting=!!model->Get_Flag(MeshGeometryClass::SORT) && WW3D::Is_Sorting_Enabled();
  194. int pass;
  195. // Figure out how many polygons we can use
  196. int active_polygon_count=0;
  197. bool arrays_used=false;
  198. for (pass=0;pass<model->Get_Pass_Count() && !arrays_used;++pass) {
  199. if (model->Has_Shader_Array(pass) || model->Has_Material_Array(pass)) {
  200. arrays_used=true;
  201. break;
  202. }
  203. for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
  204. TextureClass* texture=NULL;
  205. if (model->Has_Texture_Array(pass,stage)) {
  206. arrays_used=true;
  207. break;
  208. }
  209. }
  210. }
  211. // If any arrays are used by the mesh, count how many polygons we have that share properties.
  212. if (arrays_used) {
  213. bool stop=false;
  214. active_polygon_count=0;
  215. for (int poly=first_polygon;poly<model->Get_Polygon_Count() && !stop;++poly) {
  216. for (pass=0;pass<model->Get_Pass_Count();++pass) {
  217. if (model->Has_Shader_Array(pass)) {
  218. if (model->Get_Shader(first_polygon,pass)!=model->Get_Shader(poly,pass)) {
  219. stop=true;
  220. break;
  221. }
  222. }
  223. if (model->Has_Material_Array(pass)) {
  224. TriIndex first_tri=model->Get_Polygon_Array()[first_polygon];
  225. TriIndex cur_tri=model->Get_Polygon_Array()[poly];
  226. if (model->Peek_Material(first_tri[0],pass)!=model->Peek_Material(cur_tri[0],pass) ||
  227. model->Peek_Material(first_tri[1],pass)!=model->Peek_Material(cur_tri[1],pass) ||
  228. model->Peek_Material(first_tri[2],pass)!=model->Peek_Material(cur_tri[2],pass)) {
  229. stop=true;
  230. break;
  231. }
  232. }
  233. for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
  234. if (model->Has_Texture_Array(pass,stage)) {
  235. if (model->Peek_Texture(first_polygon,pass,stage)!=model->Peek_Texture(poly,pass,stage)) {
  236. stop=true;
  237. break;
  238. }
  239. }
  240. }
  241. }
  242. active_polygon_count++;
  243. }
  244. }
  245. FirstVisiblePolygon=first_polygon;
  246. VisiblePolygonCount=active_polygon_count;
  247. if (FirstVisiblePolygon!=0 && VisiblePolygonCount==0) {
  248. VisiblePolygonCount=model->Get_Polygon_Count()-FirstVisiblePolygon;
  249. }
  250. WWASSERT(FirstVisiblePolygon+VisiblePolygonCount<=model->Get_Polygon_Count());
  251. // Now that the definition is initialized, create a shader instance (there's really
  252. // only one def/instance pair with the legacy meshes, no optimization planned currently)
  253. ShdLegacyW3DDefClass* shader_def=NEW_REF( ShdLegacyW3DDefClass, () );
  254. Shader=shader_def->Create();
  255. REF_PTR_RELEASE(shader_def);
  256. // Danger! We're assuming Shd6LegacyW3DClass is the only type created by legacy shader!!!
  257. ((Shd6LegacyW3DClass*)Shader)->Set_FVF(Define_FVF(model,true));
  258. ((Shd6LegacyW3DClass*)Shader)->Set_Pass_Count(model->Get_Pass_Count());
  259. for (pass=0;pass<model->Get_Pass_Count();++pass) {
  260. ShaderClass legacy_shader=ShaderClass::_PresetOpaqueShader;
  261. if (model->Has_Shader_Array(pass)) {
  262. legacy_shader=model->Get_Shader(first_polygon,pass);
  263. }
  264. else {
  265. legacy_shader=model->Get_Single_Shader(pass);
  266. }
  267. VertexMaterialClass* legacy_material=NULL;
  268. if (model->Has_Material_Array(pass)) {
  269. TriIndex first_tri=model->Get_Polygon_Array()[first_polygon];
  270. legacy_material=model->Get_Material(first_tri[0],pass);
  271. }
  272. else {
  273. legacy_material=model->Get_Single_Material(pass);
  274. }
  275. for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
  276. TextureClass* texture=NULL;
  277. if (model->Has_Texture_Array(pass,stage)) {
  278. texture=model->Get_Texture(first_polygon,pass,stage);
  279. }
  280. else {
  281. texture=model->Get_Single_Texture(pass,stage);
  282. }
  283. if (texture) {
  284. // StringClass texture_name=texture->Get_Full_Path();
  285. // texture->Release_Ref();
  286. // shader_def->Set_Texture_Name(pass,stage,texture_name);
  287. ((Shd6LegacyW3DClass*)Shader)->Set_Texture(pass,stage,texture);
  288. texture->Release_Ref();
  289. }
  290. }
  291. ((Shd6LegacyW3DClass*)Shader)->Set_Shader(pass,legacy_shader);
  292. ((Shd6LegacyW3DClass*)Shader)->Set_Material(pass,legacy_material);
  293. }
  294. *(MeshGeometryClass*)this = *(MeshGeometryClass*)model;
  295. if (CullTree)
  296. CullTree->Set_Mesh(this);
  297. // Copy texture coordinates
  298. int uv_array_count=model->Get_UV_Array_Count();
  299. WWASSERT(uv_array_count<=MAX_TEXTURE_STAGES);
  300. for (int uvi=0;uvi<uv_array_count;++uvi) {
  301. const Vector2 *uv=model->Get_UV_Array_By_Index(uvi);
  302. if (uv) {
  303. UV[uvi]=NEW_REF(ShareBufferClass<Vector2>,(model->Get_Vertex_Count(),"ShdSubMeshClass::UVCoords"));
  304. memcpy(UV[uvi]->Get_Array(),uv,sizeof(Vector2)*model->Get_Vertex_Count());
  305. }
  306. }
  307. // Copy vertex color array
  308. const unsigned* diffuse=model->Get_DCG_Array(0);
  309. if (diffuse) {
  310. Diffuse=NEW_REF(ShareBufferClass<unsigned>,(model->Get_Vertex_Count(),"ShdSubMeshClass::Diffuse"));
  311. memcpy(Diffuse->Get_Array(),diffuse,sizeof(unsigned)*model->Get_Vertex_Count());
  312. }
  313. }
  314. WW3DErrorType ShdSubMeshClass::Load_W3D(ChunkLoadClass& cload)
  315. {
  316. // read header
  317. W3dShdSubMeshHeaderStruct hdr;
  318. cload.Open_Chunk();
  319. if
  320. (
  321. cload.Read
  322. (
  323. &hdr,
  324. sizeof(W3dShdSubMeshHeaderStruct)
  325. )!=sizeof(W3dShdSubMeshHeaderStruct)
  326. )
  327. {
  328. return WW3D_ERROR_LOAD_FAILED;
  329. }
  330. cload.Close_Chunk();
  331. // process header
  332. PolyCount=hdr.NumTris;
  333. VertexCount=hdr.NumVertices;
  334. if ((PolyCount!=0) && (VertexCount!=0))
  335. {
  336. Poly = NEW_REF(ShareBufferClass<TriIndex>,(PolyCount,"ShdSubMesh::Poly"));
  337. PolySurfaceType = NEW_REF(ShareBufferClass<uint8>,(PolyCount,"ShdSubMesh::PolySurfaceType"));
  338. Vertex = NEW_REF(ShareBufferClass<Vector3>,(VertexCount,"ShdSubMesh::Vertex"));
  339. Poly->Clear();
  340. PolySurfaceType->Clear();
  341. Vertex->Clear();
  342. #if (!OPTIMIZE_VNORM_RAM)
  343. VertexNorm =NEW_REF(ShareBufferClass<Vector3>,(VertexCount,"ShdSubMesh::VertexNorm"));
  344. VertexNorm->Clear();
  345. #endif
  346. }
  347. BoundBoxMin.Set(hdr.BoxMin.X,hdr.BoxMin.Y,hdr.BoxMin.Z);
  348. BoundBoxMax.Set(hdr.BoxMax.X,hdr.BoxMax.Y,hdr.BoxMax.Z);
  349. BoundSphereCenter.Set(hdr.SphCenter.X,hdr.SphCenter.Y,hdr.SphCenter.Z);
  350. BoundSphereRadius=hdr.SphRadius;
  351. read_chunks(cload);
  352. if ((Shader->Peek_Definition() != NULL) && (Shader->Peek_Definition()->Get_Class_ID() == SHDDEF_CLASSID_LEGACYW3D)) {
  353. // Danger! We're assuming Shd6LegacyW3DClass is the only type created by legacy shader!!!
  354. Shd6LegacyW3DClass * legacy_shader = (Shd6LegacyW3DClass*)Shader;
  355. legacy_shader->Set_FVF(Define_FVF(this,true));
  356. if (!legacy_shader->Is_Opaque()) {
  357. Set_Flag(MeshGeometryClass::SORT,true);
  358. }
  359. }
  360. return WW3D_ERROR_OK;
  361. }
  362. /***********************************************************************************************
  363. * ShdSubMeshClass::read_chunks -- read w3d chunks *
  364. * *
  365. * *
  366. * INPUT: *
  367. * *
  368. * OUTPUT: *
  369. * *
  370. * WARNINGS: *
  371. * *
  372. * HISTORY: *
  373. * 5/21/2002 kjm : Created. *
  374. *=============================================================================================*/
  375. WW3DErrorType ShdSubMeshClass::read_chunks(ChunkLoadClass& cload)
  376. {
  377. // If there are no more chunks within the mesh chunk,
  378. // we are done.
  379. while (cload.Open_Chunk())
  380. {
  381. // Process the chunk
  382. WW3DErrorType error=WW3D_ERROR_OK;
  383. switch (cload.Cur_Chunk_ID())
  384. {
  385. case W3D_CHUNK_SHDSUBMESH_VERTICES : error=read_vertices(cload); break;
  386. case W3D_CHUNK_SHDSUBMESH_VERTEX_NORMALS : error=read_vertex_normals(cload); break;
  387. case W3D_CHUNK_SHDSUBMESH_UV0 : error=read_uv0(cload); break;
  388. case W3D_CHUNK_SHDSUBMESH_UV1 : error=read_uv1(cload); break;
  389. case W3D_CHUNK_SHDSUBMESH_TANGENT_BASIS_S : error=read_tangent_basis_s(cload); break;
  390. case W3D_CHUNK_SHDSUBMESH_TANGENT_BASIS_T : error=read_tangent_basis_t(cload); break;
  391. case W3D_CHUNK_SHDSUBMESH_TANGENT_BASIS_SxT : error=read_tangent_basis_sxt(cload); break;
  392. case W3D_CHUNK_SHDSUBMESH_TRIANGLES : error=read_triangles(cload); break;
  393. case W3D_CHUNK_SHDSUBMESH_VERTEX_SHADE_INDICES : error=read_vertex_shade_indices(cload); break;
  394. case W3D_CHUNK_SHDSUBMESH_SHADER : error=read_shader(cload); break;
  395. case W3D_CHUNK_SHDSUBMESH_VERTEX_INFLUENCES : error=read_vertex_influences(cload); break;
  396. default: break;
  397. }
  398. cload.Close_Chunk();
  399. if (error!=WW3D_ERROR_OK)
  400. {
  401. return error;
  402. }
  403. }
  404. return WW3D_ERROR_OK;
  405. }
  406. /***********************************************************************************************
  407. * ShdSubMeshClass::read_vertices -- read the vertex chunk from a W3D file *
  408. * *
  409. * INPUT: *
  410. * *
  411. * OUTPUT: *
  412. * *
  413. * WARNINGS: *
  414. * *
  415. * HISTORY: *
  416. * 5/21/2002 kjm : Created. *
  417. *=============================================================================================*/
  418. WW3DErrorType ShdSubMeshClass::read_vertices(ChunkLoadClass& cload)
  419. {
  420. W3dVectorStruct vert;
  421. Vector3* loc=Vertex->Get_Array();
  422. assert(loc);
  423. for (int i=0; i<Get_Vertex_Count(); i++)
  424. {
  425. if (cload.Read(&vert,sizeof(W3dVectorStruct)) != sizeof(W3dVectorStruct))
  426. {
  427. return WW3D_ERROR_LOAD_FAILED;
  428. }
  429. loc[i].X=vert.X;
  430. loc[i].Y=vert.Y;
  431. loc[i].Z=vert.Z;
  432. }
  433. return WW3D_ERROR_OK;
  434. }
  435. /***********************************************************************************************
  436. * ShdSubMeshClass::read_vertex_normals -- read the vertex normals chunk from a w3d file *
  437. * *
  438. * INPUT: *
  439. * *
  440. * OUTPUT: *
  441. * *
  442. * WARNINGS: *
  443. * *
  444. * HISTORY: *
  445. * 5/21/2002 kjm : Created. *
  446. *=============================================================================================*/
  447. WW3DErrorType ShdSubMeshClass::read_vertex_normals(ChunkLoadClass& cload)
  448. {
  449. W3dVectorStruct norm;
  450. Vector3 * mdlnorms=get_vert_normals();
  451. WWASSERT(mdlnorms);
  452. for (int i=0; i<VertexCount; i++)
  453. {
  454. if (cload.Read(&norm,sizeof(W3dVectorStruct)) != sizeof(W3dVectorStruct))
  455. {
  456. return WW3D_ERROR_LOAD_FAILED;
  457. }
  458. mdlnorms[i].Set(norm.X,norm.Y,norm.Z);
  459. }
  460. return WW3D_ERROR_OK;
  461. }
  462. /***********************************************************************************************
  463. * ShdSubMeshClass::read_uv0 -- read the texture coords chunk from a w3d file *
  464. * *
  465. * INPUT: *
  466. * *
  467. * OUTPUT: *
  468. * *
  469. * WARNINGS: *
  470. * *
  471. * HISTORY: *
  472. * 5/26/2002 kjm : Created. *
  473. *=============================================================================================*/
  474. WW3DErrorType ShdSubMeshClass::read_uv0(ChunkLoadClass& cload)
  475. {
  476. UV[0]=NEW_REF(ShareBufferClass<Vector2>,(VertexCount,"ShdSubMeshClass::UV"));
  477. UV[0]->Clear();
  478. Vector2* uv=UV[0]->Get_Array();
  479. for (int i=0; i<VertexCount; i++)
  480. {
  481. if
  482. (
  483. cload.Read
  484. (
  485. uv++,
  486. sizeof(Vector2)
  487. )!=sizeof(Vector2)
  488. )
  489. {
  490. return WW3D_ERROR_LOAD_FAILED;
  491. }
  492. }
  493. return WW3D_ERROR_OK;
  494. }
  495. /***********************************************************************************************
  496. * ShdSubMeshClass::read_uv1 -- read the texture coords chunk from a w3d file *
  497. * *
  498. * INPUT: *
  499. * *
  500. * OUTPUT: *
  501. * *
  502. * WARNINGS: *
  503. * *
  504. * HISTORY: *
  505. * 5/26/2002 kjm : Created. *
  506. *=============================================================================================*/
  507. WW3DErrorType ShdSubMeshClass::read_uv1(ChunkLoadClass& cload)
  508. {
  509. UV[1]=NEW_REF(ShareBufferClass<Vector2>,(VertexCount,"ShdSubMeshClass::UV"));
  510. UV[1]->Clear();
  511. Vector2* uv=UV[1]->Get_Array();
  512. for (int i=0; i<VertexCount; i++)
  513. {
  514. if
  515. (
  516. cload.Read
  517. (
  518. uv++,
  519. sizeof(Vector2)
  520. )!=sizeof(Vector2)
  521. )
  522. {
  523. return WW3D_ERROR_LOAD_FAILED;
  524. }
  525. }
  526. return WW3D_ERROR_OK;
  527. }
  528. /***********************************************************************************************
  529. * ShdSubMeshClass::read_tangent_basis_s -- read the tangent basis chunk from a w3d file *
  530. * *
  531. * INPUT: *
  532. * *
  533. * OUTPUT: *
  534. * *
  535. * WARNINGS: *
  536. * *
  537. * HISTORY: *
  538. * 5/26/2002 kjm : Created. *
  539. *=============================================================================================*/
  540. WW3DErrorType ShdSubMeshClass::read_tangent_basis_s(ChunkLoadClass& cload)
  541. {
  542. S=NEW_REF(ShareBufferClass<Vector3>,(VertexCount,"ShdSubMeshClass::S"));
  543. S->Clear();
  544. Vector3* t=S->Get_Array();
  545. for (int i=0; i<VertexCount; i++)
  546. {
  547. if
  548. (
  549. cload.Read
  550. (
  551. t++,
  552. sizeof(Vector3)
  553. )!=sizeof(Vector3)
  554. )
  555. {
  556. return WW3D_ERROR_LOAD_FAILED;
  557. }
  558. }
  559. return WW3D_ERROR_OK;
  560. }
  561. /***********************************************************************************************
  562. * ShdSubMeshClass::read_tangent_basis_t -- read the tangent basis chunk from a w3d file *
  563. * *
  564. * INPUT: *
  565. * *
  566. * OUTPUT: *
  567. * *
  568. * WARNINGS: *
  569. * *
  570. * HISTORY: *
  571. * 5/26/2002 kjm : Created. *
  572. *=============================================================================================*/
  573. WW3DErrorType ShdSubMeshClass::read_tangent_basis_t(ChunkLoadClass& cload)
  574. {
  575. T=NEW_REF(ShareBufferClass<Vector3>,(VertexCount,"ShdSubMeshClass::T"));
  576. T->Clear();
  577. Vector3* t=T->Get_Array();
  578. for (int i=0; i<VertexCount; i++)
  579. {
  580. if
  581. (
  582. cload.Read
  583. (
  584. t++,
  585. sizeof(Vector3)
  586. )!=sizeof(Vector3)
  587. )
  588. {
  589. return WW3D_ERROR_LOAD_FAILED;
  590. }
  591. }
  592. return WW3D_ERROR_OK;
  593. }
  594. /***********************************************************************************************
  595. * ShdSubMeshClass::read_tangent_basis_sxt -- read the tangent basis chunk from a w3d file *
  596. * *
  597. * INPUT: *
  598. * *
  599. * OUTPUT: *
  600. * *
  601. * WARNINGS: *
  602. * *
  603. * HISTORY: *
  604. * 5/26/2002 kjm : Created. *
  605. *=============================================================================================*/
  606. WW3DErrorType ShdSubMeshClass::read_tangent_basis_sxt(ChunkLoadClass& cload)
  607. {
  608. SxT=NEW_REF(ShareBufferClass<Vector3>,(VertexCount,"ShdSubMeshClass::SxT"));
  609. SxT->Clear();
  610. Vector3* t=SxT->Get_Array();
  611. for (int i=0; i<VertexCount; i++)
  612. {
  613. if
  614. (
  615. cload.Read
  616. (
  617. t++,
  618. sizeof(Vector3)
  619. )!=sizeof(Vector3)
  620. )
  621. {
  622. return WW3D_ERROR_LOAD_FAILED;
  623. }
  624. }
  625. return WW3D_ERROR_OK;
  626. }
  627. /***********************************************************************************************
  628. * ShdSubMeshClass::read_vertex_influences -- read the vertex bone links from a w3d file *
  629. * *
  630. * This is for WWSKin support, presumably when we implement HW skining this may become obsolete*
  631. * *
  632. * INPUT: *
  633. * *
  634. * OUTPUT: *
  635. * *
  636. * WARNINGS: *
  637. * *
  638. * HISTORY: *
  639. * 11/07/2002 gth: Created *
  640. *=============================================================================================*/
  641. WW3DErrorType ShdSubMeshClass::read_vertex_influences(ChunkLoadClass& cload)
  642. {
  643. uint16 * bone_links = get_bone_links();
  644. for (int i=0; i<VertexCount; i++)
  645. {
  646. if
  647. (
  648. cload.Read
  649. (
  650. bone_links++,
  651. sizeof(uint8)
  652. )!=sizeof(uint8)
  653. )
  654. {
  655. return WW3D_ERROR_LOAD_FAILED;
  656. }
  657. }
  658. Set_Flag(SKIN,true);
  659. return WW3D_ERROR_OK;
  660. }
  661. /***********************************************************************************************
  662. * ShdSubMeshClass::read_triangles -- read the triangles chunk from a w3d file *
  663. * *
  664. * INPUT: *
  665. * *
  666. * OUTPUT: *
  667. * *
  668. * WARNINGS: *
  669. * *
  670. * HISTORY: *
  671. * 5/21/2002 kjm : Created. *
  672. *=============================================================================================*/
  673. WW3DErrorType ShdSubMeshClass::read_triangles(ChunkLoadClass & cload)
  674. {
  675. unsigned short tri[3];
  676. // cache pointers to various arrays in the surrender mesh
  677. TriIndex * vi = get_polys();
  678. Set_Flag(DIRTY_PLANES,false);
  679. // Vector4 * peq = get_planes();
  680. // uint8 * surface_types = Get_Poly_Surface_Type_Array();
  681. // read in each polygon one by one
  682. for (int i=0; i<Get_Polygon_Count(); i++)
  683. {
  684. if
  685. (
  686. cload.Read
  687. (
  688. tri,
  689. sizeof(unsigned short)*3
  690. )!=sizeof(unsigned short)*3
  691. )
  692. {
  693. return WW3D_ERROR_LOAD_FAILED;
  694. }
  695. // set the vertex indices
  696. vi[i].I = tri[0];
  697. vi[i].J = tri[1];
  698. vi[i].K = tri[2];
  699. // set the normal
  700. /*peq[i].X = tri.Normal.X;
  701. peq[i].Y = tri.Normal.Y;
  702. peq[i].Z = tri.Normal.Z;
  703. peq[i].W = -tri.Dist;
  704. // set the surface type
  705. WWASSERT(tri.Attributes < 256);
  706. surface_types[i] = (uint8)(tri.Attributes);*/
  707. }
  708. return WW3D_ERROR_OK;
  709. }
  710. /***********************************************************************************************
  711. * ShdSubMeshClass::read_vertex_shade_indices -- read the vertex shade indices chunk *
  712. * *
  713. * INPUT: *
  714. * *
  715. * OUTPUT: *
  716. * *
  717. * WARNINGS: *
  718. * *
  719. * HISTORY: *
  720. * 5/21/2002 kjm : Created. *
  721. *=============================================================================================*/
  722. WW3DErrorType ShdSubMeshClass::read_vertex_shade_indices(ChunkLoadClass & cload)
  723. {
  724. uint32 * shade_index = get_shade_indices(true);
  725. uint32 si;
  726. for (int i=0; i<Get_Vertex_Count(); i++)
  727. {
  728. if (cload.Read(&si,sizeof(uint32)) != sizeof(uint32))
  729. {
  730. return WW3D_ERROR_LOAD_FAILED;
  731. }
  732. shade_index[i] = si;
  733. }
  734. return WW3D_ERROR_OK;
  735. }
  736. /***********************************************************************************************
  737. * ShdSubMeshClass::read_shader -- read the shader chunk *
  738. * *
  739. * INPUT: *
  740. * *
  741. * OUTPUT: *
  742. * *
  743. * WARNINGS: *
  744. * *
  745. * HISTORY: *
  746. * 5/21/2002 kjm : Created. *
  747. *=============================================================================================*/
  748. WW3DErrorType ShdSubMeshClass::read_shader(ChunkLoadClass& cload)
  749. {
  750. // load the shader definition
  751. ShdDefClass* shddef=NULL;
  752. ShdDefManagerClass::Load_Shader(cload, &shddef);
  753. // create the shader interface
  754. Shader=shddef->Create();
  755. REF_PTR_RELEASE(shddef);
  756. return WW3D_ERROR_OK;
  757. }
  758. /***********************************************************************************************
  759. * ShdSubMesh::Get_Deformed_Vertices -- Gets the deformed vertices for a skin *
  760. * *
  761. * INPUT: *
  762. * *
  763. * OUTPUT: *
  764. * *
  765. * WARNINGS: *
  766. * *
  767. * HISTORY: *
  768. * 3/4/2001 gth : Created. *
  769. *=============================================================================================*/
  770. void ShdSubMeshClass::Get_Deformed_Vertices(Vector3 *dst_vert, Vector3 *dst_norm, const HTreeClass* htree)
  771. {
  772. WWASSERT(Get_Flag(MeshGeometryClass::SKIN));
  773. WWASSERT(htree);
  774. get_deformed_vertices(dst_vert,dst_norm,htree);
  775. }
  776. /***********************************************************************************************
  777. * ShdSubMeshClass::Get_Deformed_Vertices -- Gets the deformed vertices for a skin *
  778. * *
  779. * INPUT: *
  780. * *
  781. * OUTPUT: *
  782. * *
  783. * WARNINGS: *
  784. * *
  785. * HISTORY: *
  786. * 3/4/2001 gth : Created. *
  787. *=============================================================================================*/
  788. void ShdSubMeshClass::Get_Deformed_Vertices(Vector3 *dst_vert,const HTreeClass* htree)
  789. {
  790. WWASSERT(Get_Flag(MeshGeometryClass::SKIN));
  791. WWASSERT(htree);
  792. get_deformed_vertices(dst_vert,htree);
  793. }