PageRenderTime 63ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 1ms

/Game/Src/ColladaMeshFormat/ColladaMeshFormatLoader.cs

https://bitbucket.org/drjedd/krill
C# | 3578 lines | 2797 code | 634 blank | 147 comment | 483 complexity | b9461053347adf456fb7fc9c081bed39 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (C) 2006-2011 NeoAxis Group Ltd.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Runtime.InteropServices;
  5. using System.IO;
  6. using Engine;
  7. using Engine.FileSystem;
  8. using Engine.Renderer;
  9. using Engine.MathEx;
  10. using Engine.Utils;
  11. using GAPLA_COMMON;
  12. using System.Xml;
  13. using GeneralMeshUtils;
  14. namespace ColladaMeshFormat
  15. {
  16. [CustomMeshFormatLoaderExtensions( new string[] { "dae" } )]
  17. public class ColladaMeshFormatLoader : CustomMeshFormatLoader
  18. {
  19. string currentFileName;
  20. Mesh currentMesh;
  21. float globalScale = 1;
  22. bool yAxisUp = true;
  23. ColladaExportingTools colladaExportingTool = ColladaExportingTools.Unknown;
  24. //parsed material info
  25. Dictionary<string, string> generatedEffects;//<effectId, materialId>
  26. Dictionary<string, string> generatedBindedMaterials;//<materialId, originalMaterialName>
  27. Dictionary<string, MySceneMaterial> generatedMaterials;//<material name, material>
  28. Dictionary<string, string> generatedImages;//<imageId, textureFilePath>
  29. Dictionary<string, GeometryItem> generatedGeometries;
  30. List<MySceneSubMesh> generatedSubMeshes;
  31. /////////////////////////////////////////////////////////////////////////////////////////////
  32. class MySceneMaterial : ISceneMaterial
  33. {
  34. string name;
  35. ColorValue diffuseColor = new ColorValue( 1, 1, 1 );
  36. string diffuse1Map = "";
  37. string diffuse2Map = "";
  38. string diffuse3Map = "";
  39. string diffuse4Map = "";
  40. string diffuse1TexCoord = "";
  41. string diffuse2TexCoord = "";
  42. string diffuse3TexCoord = "";
  43. string diffuse4TexCoord = "";
  44. string diffuse2MapBlending = "";
  45. string diffuse3MapBlending = "";
  46. string diffuse4MapBlending = "";
  47. string specularMap = "";
  48. string specularTexCoord;
  49. ColorValue specularColor;
  50. string emissionMap = "";
  51. string emissionTexCoord;
  52. ColorValue emissionColor;
  53. float shininess;
  54. float transparency;
  55. ColorValue transparentColor;
  56. bool opaque;
  57. bool culling = true;
  58. //
  59. public MySceneMaterial( string name )
  60. {
  61. this.name = name;
  62. }
  63. public string Name
  64. {
  65. get { return name; }
  66. set { name = value; }
  67. }
  68. public ColorValue DiffuseColor
  69. {
  70. get { return diffuseColor; }
  71. set { diffuseColor = value; }
  72. }
  73. public string Diffuse1Map
  74. {
  75. get { return diffuse1Map; }
  76. set { diffuse1Map = value; }
  77. }
  78. public string Diffuse2Map
  79. {
  80. get { return diffuse2Map; }
  81. set { diffuse2Map = value; }
  82. }
  83. public string Diffuse3Map
  84. {
  85. get { return diffuse3Map; }
  86. set { diffuse3Map = value; }
  87. }
  88. public string Diffuse4Map
  89. {
  90. get { return diffuse4Map; }
  91. set { diffuse4Map = value; }
  92. }
  93. public string Diffuse1TexCoord
  94. {
  95. get { return diffuse1TexCoord; }
  96. set { diffuse1TexCoord = value; }
  97. }
  98. public string Diffuse2TexCoord
  99. {
  100. get { return diffuse2TexCoord; }
  101. set { diffuse2TexCoord = value; }
  102. }
  103. public string Diffuse3TexCoord
  104. {
  105. get { return diffuse3TexCoord; }
  106. set { diffuse3TexCoord = value; }
  107. }
  108. public string Diffuse4TexCoord
  109. {
  110. get { return diffuse4TexCoord; }
  111. set { diffuse4TexCoord = value; }
  112. }
  113. public string Diffuse2MapBlending
  114. {
  115. get { return diffuse2MapBlending; }
  116. set { diffuse2MapBlending = value; }
  117. }
  118. public string Diffuse3MapBlending
  119. {
  120. get { return diffuse3MapBlending; }
  121. set { diffuse3MapBlending = value; }
  122. }
  123. public string Diffuse4MapBlending
  124. {
  125. get { return diffuse4MapBlending; }
  126. set { diffuse4MapBlending = value; }
  127. }
  128. public float Transparency
  129. {
  130. get { return transparency; }
  131. set { transparency = value; }
  132. }
  133. public ColorValue TransparentColor
  134. {
  135. get { return transparentColor; }
  136. set { transparentColor = value; }
  137. }
  138. public bool Opaque
  139. {
  140. get { return opaque; }
  141. set { opaque = value; }
  142. }
  143. public float GetAlpha()
  144. {
  145. if( opaque )
  146. return transparency;
  147. if( transparentColor.Red > 0 || transparentColor.Green > 0 || transparentColor.Blue > 0 )
  148. return 1.0f - transparency;
  149. return 1;
  150. }
  151. public string SpecularMap
  152. {
  153. get { return specularMap; }
  154. set { specularMap = value; }
  155. }
  156. public string SpecularTexCoord
  157. {
  158. get { return specularTexCoord; }
  159. set { specularTexCoord = value; }
  160. }
  161. public ColorValue SpecularColor
  162. {
  163. get { return specularColor; }
  164. set { specularColor = value; }
  165. }
  166. public float Shininess
  167. {
  168. get { return shininess; }
  169. set { shininess = value; }
  170. }
  171. public string EmissionMap
  172. {
  173. get { return emissionMap; }
  174. set { emissionMap = value; }
  175. }
  176. public string EmissionTexCoord
  177. {
  178. get { return emissionTexCoord; }
  179. set { emissionTexCoord = value; }
  180. }
  181. public ColorValue EmissionColor
  182. {
  183. get { return emissionColor; }
  184. set { emissionColor = value; }
  185. }
  186. public bool Culling
  187. {
  188. get { return culling; }
  189. set { culling = value; }
  190. }
  191. }
  192. /////////////////////////////////////////////////////////////////////////////////////////////
  193. class GeometryItem
  194. {
  195. string id;
  196. SubMesh[] subMeshes;
  197. //
  198. public class SubMesh
  199. {
  200. SubMeshVertex[] vertices;
  201. int[] indices;
  202. int textureCoordCount;
  203. bool vertexColors;
  204. MySceneMaterial material;
  205. //
  206. public SubMesh( SubMeshVertex[] vertices, int[] indices, int textureCoordCount,
  207. bool vertexColors, MySceneMaterial material )
  208. {
  209. this.vertices = vertices;
  210. this.indices = indices;
  211. this.textureCoordCount = textureCoordCount;
  212. this.vertexColors = vertexColors;
  213. this.material = material;
  214. }
  215. public SubMeshVertex[] Vertices
  216. {
  217. get { return vertices; }
  218. }
  219. public int[] Indices
  220. {
  221. get { return indices; }
  222. }
  223. public int TextureCoordCount
  224. {
  225. get { return textureCoordCount; }
  226. }
  227. public bool VertexColors
  228. {
  229. get { return vertexColors; }
  230. }
  231. public MySceneMaterial Material
  232. {
  233. get { return material; }
  234. }
  235. }
  236. //
  237. public GeometryItem( string id, SubMesh[] subMeshes )
  238. {
  239. this.id = id;
  240. this.subMeshes = subMeshes;
  241. }
  242. public string Id
  243. {
  244. get { return id; }
  245. }
  246. public SubMesh[] SubMeshes
  247. {
  248. get { return subMeshes; }
  249. }
  250. }
  251. /////////////////////////////////////////////////////////////////////////////////////////////
  252. class MySceneSubMesh : ISceneSubMesh
  253. {
  254. SubMeshVertex[] vertices;
  255. int[] indices;
  256. int textureCoordCount;
  257. bool vertexColors;
  258. MySceneMaterial material;
  259. //
  260. public MySceneSubMesh( SubMeshVertex[] vertices, int[] indices, int textureCoordCount,
  261. bool vertexColors, MySceneMaterial material )
  262. {
  263. this.vertices = vertices;
  264. this.indices = indices;
  265. this.textureCoordCount = textureCoordCount;
  266. this.vertexColors = vertexColors;
  267. this.material = material;
  268. }
  269. public void GetGeometry( out SubMeshVertex[] vertices, out int[] indices )
  270. {
  271. vertices = this.vertices;
  272. indices = this.indices;
  273. }
  274. public int GetTextureCoordCount()
  275. {
  276. return textureCoordCount;
  277. }
  278. public bool VertexColors
  279. {
  280. get { return vertexColors; }
  281. }
  282. public ISceneMaterial Material
  283. {
  284. get { return material; }
  285. }
  286. public SceneBoneAssignmentItem[] GetVertexBoneAssignment( int vertexIndex )
  287. {
  288. return null;
  289. }
  290. public void GetVerticesByTime( float timeFrame, out Vec3[] vertices, bool skeletonOn )
  291. {
  292. vertices = null;
  293. skeletonOn = false;
  294. }
  295. public bool HasPoses()
  296. {
  297. return false;
  298. }
  299. public void GetPoses( out PoseInfo[] poses )
  300. {
  301. poses = null;
  302. }
  303. public void GetPoseReferenceByTime( float timeFrame, out PoseReference[] poseReferences )
  304. {
  305. poseReferences = null;
  306. }
  307. public bool AllowCollision
  308. {
  309. get { return true; }
  310. }
  311. public UVUnwrapChannels UVUnwrapChannel
  312. {
  313. get { return UVUnwrapChannels.None; }
  314. }
  315. public bool HasVertexColors()
  316. {
  317. return vertexColors;
  318. }
  319. }
  320. /////////////////////////////////////////////////////////////////////////////////////////////
  321. class MyMeshSceneObject : IMeshSceneObject
  322. {
  323. MySceneSubMesh[] subMeshes;
  324. //
  325. public MyMeshSceneObject( MySceneSubMesh[] subMeshes )
  326. {
  327. this.subMeshes = subMeshes;
  328. }
  329. public ISceneSubMesh[] SubMeshes
  330. {
  331. get { return subMeshes; }
  332. }
  333. public IList<ISceneBone> SkinBones
  334. {
  335. get
  336. {
  337. return new ISceneBone[ 0 ];
  338. }
  339. }
  340. public int AnimationFrameRate
  341. {
  342. get
  343. {
  344. return 0;
  345. }
  346. }
  347. public void GetBoundsByTime( float timeFrame, out Bounds bounds, out float radius )
  348. {
  349. Log.Fatal( "GetBoundsByTime" );
  350. bounds = Bounds.Cleared;
  351. radius = -1;
  352. }
  353. }
  354. /////////////////////////////////////////////////////////////////////////////////////////////
  355. class SourceItem
  356. {
  357. string id;
  358. float[] data;
  359. int offset;
  360. int stride;
  361. //
  362. public SourceItem( string id, float[] data, int offset, int stride )
  363. {
  364. this.id = id;
  365. this.data = data;
  366. this.offset = offset;
  367. this.stride = stride;
  368. }
  369. public string Id
  370. {
  371. get { return id; }
  372. }
  373. public float[] Data
  374. {
  375. get { return data; }
  376. }
  377. public int Offset
  378. {
  379. get { return offset; }
  380. }
  381. public int Stride
  382. {
  383. get { return stride; }
  384. }
  385. public Vec2 GetItemVec2( int index )
  386. {
  387. int index2 = offset + index * stride;
  388. return new Vec2(
  389. data[ index2 + 0 ],
  390. data[ index2 + 1 ] );
  391. }
  392. public Vec3 GetItemVec3( int index )
  393. {
  394. int index2 = offset + index * stride;
  395. return new Vec3(
  396. data[ index2 + 0 ],
  397. data[ index2 + 1 ],
  398. data[ index2 + 2 ] );
  399. }
  400. }
  401. /////////////////////////////////////////////////////////////////////////////////////////////
  402. enum ChannelTypes
  403. {
  404. Unknown,
  405. POSITION,
  406. NORMAL,
  407. COLOR,
  408. TEXCOORD0,
  409. TEXCOORD1,
  410. TEXCOORD2,
  411. TEXCOORD3,
  412. TANGENT,
  413. }
  414. /////////////////////////////////////////////////////////////////////////////////////////////
  415. enum ColladaExportingTools
  416. {
  417. Unknown,
  418. FBX,
  419. XSI,
  420. Blender,
  421. Unwrap3d,
  422. NeoAxis,
  423. }
  424. /////////////////////////////////////////////////////////////////////////////////////////////
  425. void Error( string format, params object[] args )
  426. {
  427. Log.Warning(
  428. string.Format( "ColladaMeshFormatLoader: Cannot load file \"{0}\". ", currentFileName ) +
  429. string.Format( format, args ) );
  430. }
  431. static float[] ConvertStringToFloatArray( string str )
  432. {
  433. if( string.IsNullOrEmpty( str ) )
  434. return new float[ 0 ];
  435. string fixedStr = str.Replace( ',', '.' );
  436. string[] strings = fixedStr.Split( new char[] { ' ', '\n', '\t', '\r' },
  437. StringSplitOptions.RemoveEmptyEntries );
  438. float[] array = new float[ strings.Length ];
  439. for( int n = 0; n < strings.Length; n++ )
  440. {
  441. float value;
  442. if( !float.TryParse( strings[ n ], out value ) )
  443. return null;
  444. array[ n ] = value;
  445. }
  446. return array;
  447. }
  448. static ColorValue ConvertStringToColorValue( string str )
  449. {
  450. if( string.IsNullOrEmpty( str ) )
  451. return new ColorValue();
  452. string fixedStr = str.Replace( ',', '.' );
  453. string[] strings = fixedStr.Split( new char[] { ' ', '\n', '\t', '\r' },
  454. StringSplitOptions.RemoveEmptyEntries );
  455. ColorValue color = new ColorValue();
  456. if( strings.Length >= 3 )
  457. {
  458. float red;
  459. if( !float.TryParse( strings[ 0 ], out red ) )
  460. return color;
  461. float green;
  462. if( !float.TryParse( strings[ 1 ], out green ) )
  463. return color;
  464. float blue;
  465. if( !float.TryParse( strings[ 2 ], out blue ) )
  466. return color;
  467. color.Red = red;
  468. color.Green = green;
  469. color.Blue = blue;
  470. if( strings.Length == 4 )
  471. {
  472. float alpha;
  473. if( !float.TryParse( strings[ 3 ], out alpha ) )
  474. return color;
  475. color.Alpha = alpha;
  476. }
  477. }
  478. return color;
  479. }
  480. static int[] ConvertStringToIntArray( string str )
  481. {
  482. if( string.IsNullOrEmpty( str ) )
  483. return new int[ 0 ];
  484. string fixedStr = str.Replace( ',', '.' );
  485. string[] strings = fixedStr.Split( new char[] { ' ', '\n', '\t', '\r' },
  486. StringSplitOptions.RemoveEmptyEntries );
  487. int[] array = new int[ strings.Length ];
  488. for( int n = 0; n < strings.Length; n++ )
  489. {
  490. int value;
  491. if( !int.TryParse( strings[ n ], out value ) )
  492. return null;
  493. array[ n ] = value;
  494. }
  495. return array;
  496. }
  497. static Vec2 ConvertColladaTexCoordToNeoAxisTexCoord( Vec2 colladaTexCoord )
  498. {
  499. return new Vec2( colladaTexCoord.X, 1 - colladaTexCoord.Y );
  500. }
  501. ColladaExportingTools GetColladaExportingTool( string authoringTool )
  502. {
  503. if( authoringTool.Contains( "FBX" ) )
  504. return ColladaExportingTools.FBX;
  505. if( authoringTool.Contains( "Softimage" ) )
  506. return ColladaExportingTools.XSI;
  507. if( authoringTool.Contains( "Blender" ) )
  508. return ColladaExportingTools.Blender;
  509. if( authoringTool.Contains( "Unwrap3D" ) )
  510. return ColladaExportingTools.Unwrap3d;
  511. if( authoringTool.Contains( "NeoAxis" ) )
  512. return ColladaExportingTools.NeoAxis;
  513. return ColladaExportingTools.Unknown;
  514. }
  515. string GetVirtualPath( string colladaFileDirectory, string path )
  516. {
  517. if( path.IndexOf( "file://" ) >= 0 )
  518. path = path.Remove( 0, 7 );
  519. if( path.Length > 0 && ( path[ 0 ] == '/' || path[ 0 ] == '\\' ) )
  520. path = path.Remove( 0, 1 );
  521. if( Path.IsPathRooted( path ) )
  522. {
  523. string virtualPath = VirtualFileSystem.GetVirtualPathByReal( path );
  524. if( string.IsNullOrEmpty( virtualPath ) )
  525. virtualPath = Path.Combine( colladaFileDirectory, Path.GetFileName( path ) );
  526. return virtualPath;
  527. }
  528. else
  529. {
  530. if( path.Length > 1 && path[ 0 ] == '.' && ( path[ 1 ] == '/' || path[ 1 ] == '\\' ) )
  531. path = path.Remove( 0, 2 );
  532. return Path.Combine( colladaFileDirectory, path );
  533. }
  534. }
  535. ShaderBaseMaterial.DiffuseMapItem.MapBlendingTypes GetMapBlendingType( string blendingMode )
  536. {
  537. if( blendingMode == "ADD" )
  538. return ShaderBaseMaterial.DiffuseMapItem.MapBlendingTypes.Add;
  539. if( blendingMode == "BLEND" )
  540. return ShaderBaseMaterial.DiffuseMapItem.MapBlendingTypes.AlphaBlend;
  541. return ShaderBaseMaterial.DiffuseMapItem.MapBlendingTypes.Modulate;
  542. }
  543. ShaderBaseMaterial.TexCoordIndexes GetNeoAxisTexCoordByColladaTexCoord( string texCoord )
  544. {
  545. if( texCoord == "CHANNEL1" )
  546. return ShaderBaseMaterial.TexCoordIndexes.TexCoord1;
  547. if( texCoord == "CHANNEL2" )
  548. return ShaderBaseMaterial.TexCoordIndexes.TexCoord2;
  549. if( texCoord == "CHANNEL3" )
  550. return ShaderBaseMaterial.TexCoordIndexes.TexCoord3;
  551. return ShaderBaseMaterial.TexCoordIndexes.TexCoord0;
  552. }
  553. MySceneMaterial GetOrCreateMaterial( string materialName )
  554. {
  555. MySceneMaterial material;
  556. if( !generatedMaterials.TryGetValue( materialName, out material ) )
  557. {
  558. material = new MySceneMaterial( materialName );
  559. generatedMaterials.Add( material.Name, material );
  560. }
  561. return material;
  562. }
  563. bool ParseSource( XmlNode sourceNode, out SourceItem source )
  564. {
  565. source = null;
  566. string id = XmlUtils.GetAttribute( sourceNode, "id" );
  567. XmlNode floatArrayNode = XmlUtils.FindChildNode( sourceNode, "float_array" );
  568. if( floatArrayNode == null )
  569. {
  570. Error( "\"float_array\" node is not exists. Source: \"{0}\".", id );
  571. return false;
  572. }
  573. int floatsCount;
  574. if( !int.TryParse( XmlUtils.GetAttribute( floatArrayNode, "count" ), out floatsCount ) )
  575. {
  576. Error( "Invalid \"count\" attribute of floats array. Source: \"{0}\".", id );
  577. return false;
  578. }
  579. float[] data = ConvertStringToFloatArray( floatArrayNode.InnerText );
  580. if( data == null )
  581. {
  582. Error( "Cannot read array with name \"{0}\".", XmlUtils.GetAttribute( floatArrayNode, "id" ) );
  583. return false;
  584. }
  585. if( data.Length != floatsCount )
  586. {
  587. Error( "Invalid amount of items in \"float_array\". Required amount: \"{0}\". " +
  588. "Real amount: \"{1}\". Source: \"{2}\".", floatsCount, data.Length, id );
  589. return false;
  590. }
  591. XmlNode techniqueCommonNode = XmlUtils.FindChildNode( sourceNode, "technique_common" );
  592. if( techniqueCommonNode == null )
  593. {
  594. Error( "\"technique_common\" node is not exists. Source: \"{0}\".", id );
  595. return false;
  596. }
  597. XmlNode accessorNode = XmlUtils.FindChildNode( techniqueCommonNode, "accessor" );
  598. if( accessorNode == null )
  599. {
  600. Error( "\"accessor\" node is not exists. Source: \"{0}\".", id );
  601. return false;
  602. }
  603. int offset = 0;
  604. {
  605. string offsetAttribute = XmlUtils.GetAttribute( accessorNode, "offset" );
  606. if( !string.IsNullOrEmpty( offsetAttribute ) )
  607. {
  608. if( !int.TryParse( offsetAttribute, out offset ) )
  609. {
  610. Error( "Invalid \"offset\" attribute of accessor. Source: \"{0}\".", id );
  611. return false;
  612. }
  613. }
  614. }
  615. int stride = 1;
  616. {
  617. string strideAttribute = XmlUtils.GetAttribute( accessorNode, "stride" );
  618. if( !string.IsNullOrEmpty( strideAttribute ) )
  619. {
  620. if( !int.TryParse( strideAttribute, out stride ) )
  621. {
  622. Error( "Invalid \"stride\" attribute of accessor. Source: \"{0}\".", id );
  623. return false;
  624. }
  625. }
  626. }
  627. int count;
  628. if( !int.TryParse( XmlUtils.GetAttribute( accessorNode, "count" ), out count ) )
  629. {
  630. Error( "Invalid \"count\" attribute of accessor. Source: \"{0}\".", id );
  631. return false;
  632. }
  633. source = new SourceItem( id, data, offset, stride );
  634. return true;
  635. }
  636. bool ParseMeshSources( XmlNode meshNode, out List<SourceItem> sources )
  637. {
  638. sources = new List<SourceItem>();
  639. foreach( XmlNode childNode in meshNode.ChildNodes )
  640. {
  641. if( childNode.Name != "source" )
  642. continue;
  643. SourceItem source;
  644. if( !ParseSource( childNode, out source ) )
  645. return false;
  646. sources.Add( source );
  647. }
  648. return true;
  649. }
  650. string GetIdFromURL( string url )
  651. {
  652. if( string.IsNullOrEmpty( url ) )
  653. return "";
  654. if( url[ 0 ] != '#' )
  655. return "";
  656. return url.Substring( 1 );
  657. }
  658. bool ParseInputNode( string geometryId, Dictionary<string, string> vertexSemanticDictionary,
  659. XmlNode inputNode, out int offset, out string sourceId, out ChannelTypes channelType )
  660. {
  661. offset = 0;
  662. sourceId = null;
  663. channelType = ChannelTypes.Unknown;
  664. //offset
  665. if( !int.TryParse( XmlUtils.GetAttribute( inputNode, "offset" ), out offset ) )
  666. {
  667. Error( "Invalid \"offset\" attribute. Geometry: \"{0}\".", geometryId );
  668. return false;
  669. }
  670. string semantic = XmlUtils.GetAttribute( inputNode, "semantic" );
  671. //channelType
  672. {
  673. int set = 0;
  674. {
  675. string setAsString = XmlUtils.GetAttribute( inputNode, "set" );
  676. if( !string.IsNullOrEmpty( setAsString ) )
  677. {
  678. if( !int.TryParse( setAsString, out set ) )
  679. {
  680. Error( "Invalid \"set\" attribute. Geometry: \"{0}\".", geometryId );
  681. return false;
  682. }
  683. }
  684. }
  685. if( semantic == "VERTEX" )
  686. channelType = ChannelTypes.POSITION;
  687. else if( semantic == "POSITION" )
  688. channelType = ChannelTypes.POSITION;
  689. else if( semantic == "NORMAL" )
  690. channelType = ChannelTypes.NORMAL;
  691. else if( semantic == "COLOR" )
  692. channelType = ChannelTypes.COLOR;
  693. else if( semantic == "TEXCOORD" )
  694. {
  695. switch( set )
  696. {
  697. case 0: channelType = ChannelTypes.TEXCOORD0; break;
  698. case 1: channelType = ChannelTypes.TEXCOORD1; break;
  699. case 2: channelType = ChannelTypes.TEXCOORD2; break;
  700. case 3: channelType = ChannelTypes.TEXCOORD3; break;
  701. default: channelType = ChannelTypes.Unknown; break;
  702. }
  703. }
  704. else if( semantic == "TANGENT" )
  705. channelType = ChannelTypes.TANGENT;
  706. else
  707. {
  708. channelType = ChannelTypes.Unknown;
  709. }
  710. }
  711. //sourceId
  712. {
  713. string sourceUrl = XmlUtils.GetAttribute( inputNode, "source" );
  714. sourceId = GetIdFromURL( sourceUrl );
  715. if( string.IsNullOrEmpty( sourceId ) )
  716. {
  717. Error( "Invalid \"source\" attribute for input node. Source url: \"{0}\". Geometry: \"{1}\".",
  718. sourceUrl, geometryId );
  719. return false;
  720. }
  721. if( semantic == "VERTEX" )
  722. {
  723. string newSourceId;
  724. if( !vertexSemanticDictionary.TryGetValue( sourceId, out newSourceId ) )
  725. {
  726. Error( "Cannot find vertices node with \"{0}\". Geometry: \"{1}\".",
  727. sourceId, geometryId );
  728. return false;
  729. }
  730. sourceId = newSourceId;
  731. }
  732. }
  733. return true;
  734. }
  735. bool ParseInputs( string geometryId, Dictionary<string, SourceItem> sourceDictionary,
  736. Dictionary<string, string> vertexSemanticDictionary, XmlNode primitiveElementsNode,
  737. out Pair<ChannelTypes, SourceItem>[] inputs )
  738. {
  739. inputs = null;
  740. List<Pair<ChannelTypes, SourceItem>> inputList = new List<Pair<ChannelTypes, SourceItem>>();
  741. foreach( XmlNode inputNode in primitiveElementsNode.ChildNodes )
  742. {
  743. if( inputNode.Name != "input" )
  744. continue;
  745. int offset;
  746. string sourceId;
  747. ChannelTypes channelType;
  748. if( !ParseInputNode( geometryId, vertexSemanticDictionary, inputNode, out offset, out sourceId,
  749. out channelType ) )
  750. {
  751. return false;
  752. }
  753. while( inputList.Count < offset + 1 )
  754. inputList.Add( new Pair<ChannelTypes, SourceItem>( ChannelTypes.Unknown, null ) );
  755. if( channelType != ChannelTypes.Unknown )
  756. {
  757. if( inputList[ offset ].Second != null )
  758. {
  759. Error( "Input with offset \"{0}\" is already defined.", offset );
  760. return false;
  761. }
  762. SourceItem source;
  763. if( !sourceDictionary.TryGetValue( sourceId, out source ) )
  764. {
  765. Error( "Source with id \"{0}\" is not exists.", sourceId );
  766. return false;
  767. }
  768. inputList[ offset ] = new Pair<ChannelTypes, SourceItem>( channelType, source );
  769. }
  770. }
  771. inputs = inputList.ToArray();
  772. return true;
  773. }
  774. SubMeshVertex[] GenerateSubMeshVertices( Pair<ChannelTypes, SourceItem>[] inputs, int vertexCount,
  775. int[] indices, int startIndex )
  776. {
  777. SubMeshVertex[] itemVertices = new SubMeshVertex[ vertexCount ];
  778. int currentIndex = startIndex;
  779. for( int nVertex = 0; nVertex < itemVertices.Length; nVertex++ )
  780. {
  781. SubMeshVertex vertex = new SubMeshVertex();
  782. foreach( Pair<ChannelTypes, SourceItem> input in inputs )
  783. {
  784. ChannelTypes channelType = input.First;
  785. SourceItem source = input.Second;
  786. int indexValue = indices[ currentIndex ];
  787. currentIndex++;
  788. switch( channelType )
  789. {
  790. case ChannelTypes.POSITION:
  791. vertex.position = source.GetItemVec3( indexValue );
  792. break;
  793. case ChannelTypes.NORMAL:
  794. vertex.normal = source.GetItemVec3( indexValue );
  795. break;
  796. case ChannelTypes.TEXCOORD0:
  797. vertex.texCoord0 = ConvertColladaTexCoordToNeoAxisTexCoord(
  798. source.GetItemVec2( indexValue ) );
  799. break;
  800. case ChannelTypes.TEXCOORD1:
  801. vertex.texCoord1 = ConvertColladaTexCoordToNeoAxisTexCoord(
  802. source.GetItemVec2( indexValue ) );
  803. break;
  804. case ChannelTypes.TEXCOORD2:
  805. vertex.texCoord2 = ConvertColladaTexCoordToNeoAxisTexCoord(
  806. source.GetItemVec2( indexValue ) );
  807. break;
  808. case ChannelTypes.TEXCOORD3:
  809. vertex.texCoord3 = ConvertColladaTexCoordToNeoAxisTexCoord(
  810. source.GetItemVec2( indexValue ) );
  811. break;
  812. case ChannelTypes.COLOR:
  813. {
  814. Vec3 c = source.GetItemVec3( indexValue ); ;
  815. vertex.color = new ColorValue( c.X, c.Y, c.Z, 1 );
  816. }
  817. break;
  818. //maybe need use "TEXTANGENT".
  819. //case ChannelTypes.TANGENT:
  820. // vertex.tangent = source.GetItemVec3( indexValue );
  821. // break;
  822. }
  823. }
  824. itemVertices[ nVertex ] = vertex;
  825. }
  826. return itemVertices;
  827. }
  828. bool ParseMeshNode( string geometryId, XmlNode meshNode )
  829. {
  830. List<SourceItem> sources;
  831. if( !ParseMeshSources( meshNode, out sources ) )
  832. return false;
  833. Dictionary<string, SourceItem> sourceDictionary = new Dictionary<string, SourceItem>();
  834. foreach( SourceItem source in sources )
  835. sourceDictionary.Add( source.Id, source );
  836. //vertexSemanticDictionary
  837. Dictionary<string, string> vertexSemanticDictionary = new Dictionary<string, string>();
  838. {
  839. foreach( XmlNode verticesNode in meshNode.ChildNodes )
  840. {
  841. if( verticesNode.Name != "vertices" )
  842. continue;
  843. string id = XmlUtils.GetAttribute( verticesNode, "id" );
  844. XmlNode inputNode = XmlUtils.FindChildNode( verticesNode, "input" );
  845. if( inputNode == null )
  846. {
  847. Error( "\"input\" node is not defined for vertices node \"{0}\". Geometry: \"{1}\".",
  848. id, geometryId );
  849. return false;
  850. }
  851. string sourceUrl = XmlUtils.GetAttribute( inputNode, "source" );
  852. string sourceId = GetIdFromURL( sourceUrl );
  853. if( string.IsNullOrEmpty( sourceId ) )
  854. {
  855. Error( "Invalid \"source\" attribute for vertices node \"{0}\". Source url: \"{1}\". " +
  856. "Geometry: \"{2}\".", id, sourceUrl, geometryId );
  857. return false;
  858. }
  859. vertexSemanticDictionary.Add( id, sourceId );
  860. }
  861. }
  862. List<GeometryItem.SubMesh> geometrySubMeshes = new List<GeometryItem.SubMesh>();
  863. //polygons, triangles, ...
  864. foreach( XmlNode primitiveElementsNode in meshNode.ChildNodes )
  865. {
  866. bool lines = primitiveElementsNode.Name == "lines";
  867. bool linestrips = primitiveElementsNode.Name == "linestrips";
  868. bool polygons = primitiveElementsNode.Name == "polygons";
  869. bool polylist = primitiveElementsNode.Name == "polylist";
  870. bool triangles = primitiveElementsNode.Name == "triangles";
  871. bool trifans = primitiveElementsNode.Name == "trifans";
  872. bool tristrips = primitiveElementsNode.Name == "tristrips";
  873. if( lines || linestrips || trifans || tristrips )
  874. {
  875. Log.Warning( "\"{0}\" primitive element is not supported. Geometry: \"{1}\". " +
  876. "\n\nElement was skipped.", primitiveElementsNode.Name, geometryId );
  877. continue;
  878. }
  879. if( polygons || triangles || polylist )
  880. {
  881. int itemCount;
  882. if( !int.TryParse( XmlUtils.GetAttribute( primitiveElementsNode, "count" ), out itemCount ) )
  883. {
  884. Error( "Invalid \"count\" attribute of \"{0}\". Geometry: \"{1}\".",
  885. primitiveElementsNode.Name, geometryId );
  886. return false;
  887. }
  888. Pair<ChannelTypes, SourceItem>[] inputs;
  889. if( !ParseInputs( geometryId, sourceDictionary, vertexSemanticDictionary,
  890. primitiveElementsNode, out inputs ) )
  891. {
  892. return false;
  893. }
  894. int textureCoordCount = 0;
  895. bool vertexColors = false;
  896. {
  897. foreach( Pair<ChannelTypes, SourceItem> input in inputs )
  898. {
  899. ChannelTypes channelType = input.First;
  900. if( channelType >= ChannelTypes.TEXCOORD0 && channelType <= ChannelTypes.TEXCOORD3 )
  901. {
  902. int v = channelType - ChannelTypes.TEXCOORD0;
  903. if( ( v + 1 ) > textureCoordCount )
  904. textureCoordCount = v + 1;
  905. }
  906. if( channelType == ChannelTypes.COLOR )
  907. vertexColors = true;
  908. }
  909. }
  910. List<SubMeshVertex> vertices = new List<SubMeshVertex>( itemCount );
  911. if( polygons )
  912. {
  913. foreach( XmlNode pNode in primitiveElementsNode.ChildNodes )
  914. {
  915. if( pNode.Name != "p" )
  916. continue;
  917. int[] indexValues = ConvertStringToIntArray( pNode.InnerText );
  918. if( indexValues == null )
  919. {
  920. Error( "Cannot read index array of geometry \"{0}\".", geometryId );
  921. return false;
  922. }
  923. int vertexCount = indexValues.Length / inputs.Length;
  924. SubMeshVertex[] itemVertices = GenerateSubMeshVertices( inputs,
  925. vertexCount, indexValues, 0 );
  926. //generate triangles
  927. for( int n = 1; n < itemVertices.Length - 1; n++ )
  928. {
  929. vertices.Add( itemVertices[ 0 ] );
  930. vertices.Add( itemVertices[ n ] );
  931. vertices.Add( itemVertices[ n + 1 ] );
  932. }
  933. }
  934. }
  935. if( triangles )
  936. {
  937. XmlNode pNode = XmlUtils.FindChildNode( primitiveElementsNode, "p" );
  938. if( pNode != null )
  939. {
  940. int[] indexValues = ConvertStringToIntArray( pNode.InnerText );
  941. if( indexValues == null )
  942. {
  943. Error( "Cannot read \"p\" node of geometry \"{0}\".", geometryId );
  944. return false;
  945. }
  946. int vertexCount = indexValues.Length / inputs.Length;
  947. if( itemCount != vertexCount / 3 )
  948. {
  949. Error( "Invalid item amount of \"p\" node of geometry \"{0}\".", geometryId );
  950. return false;
  951. }
  952. SubMeshVertex[] itemVertices = GenerateSubMeshVertices( inputs,
  953. vertexCount, indexValues, 0 );
  954. //generate triangles
  955. for( int n = 0; n < vertexCount; n++ )
  956. vertices.Add( itemVertices[ n ] );
  957. }
  958. }
  959. if( polylist )
  960. {
  961. XmlNode vCountNode = XmlUtils.FindChildNode( primitiveElementsNode, "vcount" );
  962. XmlNode pNode = XmlUtils.FindChildNode( primitiveElementsNode, "p" );
  963. if( vCountNode != null && pNode != null )
  964. {
  965. int[] vCount = ConvertStringToIntArray( vCountNode.InnerText );
  966. if( vCount == null )
  967. {
  968. Error( "Cannot read \"vcount\" node of geometry \"{0}\".", geometryId );
  969. return false;
  970. }
  971. if( vCount.Length != itemCount )
  972. {
  973. Error( "Invalid item amount of \"vcount\" node of geometry \"{0}\".", geometryId );
  974. return false;
  975. }
  976. int[] indexValues = ConvertStringToIntArray( pNode.InnerText );
  977. if( indexValues == null )
  978. {
  979. Error( "Cannot read \"p\" node of geometry \"{0}\".", geometryId );
  980. return false;
  981. }
  982. int currentIndex = 0;
  983. foreach( int polyCount in vCount )
  984. {
  985. SubMeshVertex[] itemVertices = GenerateSubMeshVertices( inputs, polyCount,
  986. indexValues, currentIndex );
  987. currentIndex += polyCount * inputs.Length;
  988. //generate triangles
  989. for( int n = 1; n < itemVertices.Length - 1; n++ )
  990. {
  991. vertices.Add( itemVertices[ 0 ] );
  992. vertices.Add( itemVertices[ n ] );
  993. vertices.Add( itemVertices[ n + 1 ] );
  994. }
  995. }
  996. if( currentIndex != indexValues.Length )
  997. {
  998. Error( "Invalid indices of geometry \"{0}\".", geometryId );
  999. return false;
  1000. }
  1001. }
  1002. }
  1003. if( vertices.Count != 0 )
  1004. {
  1005. int[] indices = new int[ vertices.Count ];
  1006. for( int n = 0; n < indices.Length; n++ )
  1007. indices[ n ] = n;
  1008. MySceneMaterial material = null;
  1009. {
  1010. string materialName = XmlUtils.GetAttribute( primitiveElementsNode, "material" );
  1011. if( !string.IsNullOrEmpty( materialName ) )
  1012. material = GetOrCreateMaterial( materialName );
  1013. }
  1014. //add to geometrySubMeshes
  1015. GeometryItem.SubMesh geometrySubMesh = new GeometryItem.SubMesh(
  1016. vertices.ToArray(), indices, textureCoordCount, vertexColors, material );
  1017. geometrySubMeshes.Add( geometrySubMesh );
  1018. }
  1019. continue;
  1020. }
  1021. }
  1022. //add to generatedGeometries
  1023. {
  1024. GeometryItem geometry = new GeometryItem( geometryId, geometrySubMeshes.ToArray() );
  1025. generatedGeometries.Add( geometry.Id, geometry );
  1026. }
  1027. return true;
  1028. }
  1029. bool ParseGeometry( XmlNode geometryNode )
  1030. {
  1031. string geometryId = XmlUtils.GetAttribute( geometryNode, "id" );
  1032. //find mesh node
  1033. XmlNode meshNode = XmlUtils.FindChildNode( geometryNode, "mesh" );
  1034. if( meshNode == null )
  1035. {
  1036. Error( "Mesh node is not exists for geometry \"{0}\".", geometryId );
  1037. return false;
  1038. }
  1039. if( !ParseMeshNode( geometryId, meshNode ) )
  1040. return false;
  1041. return true;
  1042. }
  1043. bool ParseGeometries( XmlNode colladaNode )
  1044. {
  1045. foreach( XmlNode libraryGeometriesNode in colladaNode.ChildNodes )
  1046. {
  1047. if( libraryGeometriesNode.Name != "library_geometries" )
  1048. continue;
  1049. foreach( XmlNode geometryNode in libraryGeometriesNode.ChildNodes )
  1050. {
  1051. if( geometryNode.Name != "geometry" )
  1052. continue;
  1053. if( !ParseGeometry( geometryNode ) )
  1054. return false;
  1055. }
  1056. }
  1057. return true;
  1058. }
  1059. bool ParseNodeInstanceGeometry( Mat4 nodeTransform, XmlNode instanceGeometry )
  1060. {
  1061. string url = XmlUtils.GetAttribute( instanceGeometry, "url" );
  1062. bool nodeTransformIdentity = nodeTransform.Equals( Mat4.Identity, .0001f );
  1063. string geometryId = GetIdFromURL( url );
  1064. if( string.IsNullOrEmpty( geometryId ) )
  1065. {
  1066. Error( "Invalid \"url\" attribute specified for \"instance_geometry\". Url: \"{0}\".", url );
  1067. return false;
  1068. }
  1069. GeometryItem geometry;
  1070. if( !generatedGeometries.TryGetValue( geometryId, out geometry ) )
  1071. {
  1072. Error( "Geometry with id \"{0}\" is not exists.", geometryId );
  1073. return false;
  1074. }
  1075. foreach( GeometryItem.SubMesh geometrySubMesh in geometry.SubMeshes )
  1076. {
  1077. SubMeshVertex[] newVertices = new SubMeshVertex[ geometrySubMesh.Vertices.Length ];
  1078. for( int n = 0; n < newVertices.Length; n++ )
  1079. {
  1080. SubMeshVertex vertex = geometrySubMesh.Vertices[ n ];
  1081. if( !nodeTransformIdentity )
  1082. {
  1083. Vec3 oldPosition = vertex.position;
  1084. vertex.position = nodeTransform * vertex.position;
  1085. Vec3 p2 = nodeTransform * ( oldPosition + vertex.normal );
  1086. vertex.normal = ( p2 - vertex.position ).GetNormalize();
  1087. }
  1088. newVertices[ n ] = vertex;
  1089. }
  1090. MySceneSubMesh sceneSubMesh = new MySceneSubMesh( newVertices, geometrySubMesh.Indices,
  1091. geometrySubMesh.TextureCoordCount, geometrySubMesh.VertexColors, geometrySubMesh.Material );
  1092. generatedSubMeshes.Add( sceneSubMesh );
  1093. }
  1094. XmlNode bindMaterialNode = XmlUtils.FindChildNode( instanceGeometry, "bind_material" );
  1095. if( bindMaterialNode != null )
  1096. {
  1097. XmlNode techniqueCommonNode = XmlUtils.FindChildNode( bindMaterialNode, "technique_common" );
  1098. if( techniqueCommonNode == null )
  1099. {
  1100. Error( "Technique_common node is not exists for geometry \"{0}\".", geometryId );
  1101. return false;
  1102. }
  1103. foreach( XmlNode instanceMaterialNode in techniqueCommonNode.ChildNodes )
  1104. {
  1105. if( instanceMaterialNode.Name == "instance_material" )
  1106. {
  1107. string target = GetIdFromURL( XmlUtils.GetAttribute( instanceMaterialNode, "target" ) );
  1108. string symbol = XmlUtils.GetAttribute( instanceMaterialNode, "symbol" );
  1109. if( !generatedBindedMaterials.ContainsKey( target ) )
  1110. generatedBindedMaterials.Add( target, symbol );
  1111. }
  1112. }
  1113. }
  1114. return true;
  1115. }
  1116. bool ParseNode( Mat4 nodeTransform, XmlNode node )
  1117. {
  1118. string nodeId = XmlUtils.GetAttribute( node, "id" );
  1119. Mat4 currentTransform = nodeTransform;
  1120. foreach( XmlNode childNode in node.ChildNodes )
  1121. {
  1122. if( childNode.Name == "matrix" )
  1123. {
  1124. float[] values = ConvertStringToFloatArray( childNode.InnerText );
  1125. if( values == null || values.Length != 16 )
  1126. {
  1127. Error( "Invalid format of \"matrix\" node. Node \"{0}\".", nodeId );
  1128. return false;
  1129. }
  1130. Mat4 matrix = new Mat4( values );
  1131. currentTransform *= matrix;
  1132. continue;
  1133. }
  1134. if( childNode.Name == "translate" )
  1135. {
  1136. float[] values = ConvertStringToFloatArray( childNode.InnerText );
  1137. if( values == null || values.Length != 3 )
  1138. {
  1139. Error( "Invalid format of \"translate\" node. Node \"{0}\".", nodeId );
  1140. return false;
  1141. }
  1142. Vec3 translate = new Vec3( values[ 0 ], values[ 1 ], values[ 2 ] );
  1143. currentTransform *= Mat4.FromTranslate( translate );
  1144. continue;
  1145. }
  1146. if( childNode.Name == "rotate" )
  1147. {
  1148. float[] values = ConvertStringToFloatArray( childNode.InnerText );
  1149. if( values == null || values.Length != 4 )
  1150. {
  1151. Error( "Invalid format of \"rotate\" node. Node \"{0}\".", nodeId );
  1152. return false;
  1153. }
  1154. Vec3 axis = new Vec3( values[ 0 ], values[ 1 ], values[ 2 ] );
  1155. Radian angle = new Degree( values[ 3 ] ).InRadians();
  1156. if( axis != Vec3.Zero )
  1157. {
  1158. axis.Normalize();
  1159. float halfAngle = .5f * angle;
  1160. float sin = MathFunctions.Sin( halfAngle );
  1161. float cos = MathFunctions.Cos( halfAngle );
  1162. Quat r = new Quat( axis * sin, cos );
  1163. r.Normalize();
  1164. currentTransform *= r.ToMat3().ToMat4();
  1165. }
  1166. continue;
  1167. }
  1168. if( childNode.Name == "scale" )
  1169. {
  1170. float[] values = ConvertStringToFloatArray( childNode.InnerText );
  1171. if( values == null || values.Length != 3 )
  1172. {
  1173. Error( "Invalid format of \"scale\" node. Node \"{0}\".", nodeId );
  1174. return false;
  1175. }
  1176. Vec3 scale = new Vec3( values[ 0 ], values[ 1 ], values[ 2 ] );
  1177. currentTransform *= Mat3.FromScale( scale ).ToMat4();
  1178. continue;
  1179. }
  1180. if( childNode.Name == "node" )
  1181. {
  1182. if( !ParseNode( currentTransform, childNode ) )
  1183. return false;
  1184. continue;
  1185. }
  1186. if( childNode.Name == "instance_geometry" )
  1187. {
  1188. if( !ParseNodeInstanceGeometry( currentTransform, childNode ) )
  1189. return false;
  1190. continue;
  1191. }
  1192. }
  1193. return true;
  1194. }
  1195. bool ParseImage( XmlNode imageNode )
  1196. {
  1197. string imageId = XmlUtils.GetAttribute( imageNode, "id" );
  1198. //find profile node
  1199. XmlNode initFromNode = XmlUtils.FindChildNode( imageNode, "init_from" );
  1200. if( initFromNode == null )
  1201. {
  1202. Error( "Init_from node is not exists for image \"{0}\".", imageId );
  1203. return false;
  1204. }
  1205. generatedImages.Add( imageId, initFromNode.InnerText );
  1206. return true;
  1207. }
  1208. bool ParseImages( XmlNode colladaNode )
  1209. {
  1210. foreach( XmlNode libraryImagesNode in colladaNode.ChildNodes )
  1211. {
  1212. if( libraryImagesNode.Name != "library_images" )
  1213. continue;
  1214. foreach( XmlNode imageNode in libraryImagesNode.ChildNodes )
  1215. {
  1216. if( imageNode.Name != "image" )
  1217. continue;
  1218. if( !ParseImage( imageNode ) )
  1219. return false;
  1220. }
  1221. }
  1222. return true;
  1223. }
  1224. bool ParseMaterial( XmlNode materialNode )
  1225. {
  1226. string materialId = XmlUtils.GetAttribute( materialNode, "id" );
  1227. string materialName = XmlUtils.GetAttribute( materialNode, "name" );
  1228. //find profile node
  1229. XmlNode instanceEffectNode = XmlUtils.FindChildNode( materialNode, "instance_effect" );
  1230. if( instanceEffectNode == null )
  1231. {
  1232. Error( "Instance_effect node is not exists for material \"{0}\".", materialId );
  1233. return false;
  1234. }
  1235. string effectId = GetIdFromURL( XmlUtils.GetAttribute( instanceEffectNode, "url" ) );
  1236. generatedEffects.Add( effectId, materialId );
  1237. return true;
  1238. }
  1239. bool ParseMaterials( XmlNode colladaNode )
  1240. {
  1241. foreach( XmlNode libraryMaterialsNode in colladaNode.ChildNodes )
  1242. {
  1243. if( libraryMaterialsNode.Name != "library_materials" )
  1244. continue;
  1245. foreach( XmlNode materialNode in libraryMaterialsNode.ChildNodes )
  1246. {
  1247. if( materialNode.Name != "material" )
  1248. continue;
  1249. if( !ParseMaterial( materialNode ) )
  1250. return false;
  1251. }
  1252. }
  1253. return true;
  1254. }
  1255. bool ParseTextureBlendingMode( XmlNode textureNode, out string blendingMode,
  1256. string materialAttributeName )
  1257. {
  1258. blendingMode = "";
  1259. XmlNode extraNode = XmlUtils.FindChildNode( textureNode, "extra" );
  1260. if( extraNode == null )
  1261. {
  1262. return true;
  1263. }
  1264. XmlNode techniqueNode = XmlUtils.FindChildNode( extraNode, "technique" );
  1265. if( techniqueNode == null )
  1266. {
  1267. Error( "Technique node is not exists for texture node of matterial attribute \"{0}\".",
  1268. materialAttributeName );
  1269. return false;
  1270. }
  1271. XmlNode blendMode = XmlUtils.FindChildNode( techniqueNode, "blend_mode" );
  1272. if( techniqueNode == null )
  1273. {
  1274. Error( "Blend_mode node is not exists for technique node of matterial attribute \"{0}\".",
  1275. materialAttributeName );
  1276. return false;
  1277. }
  1278. blendingMode = blendMode.InnerText;
  1279. return true;
  1280. }
  1281. bool ParseEffectAttribute( XmlNode materialAttributeNode, ref ColorValue color,
  1282. ref string textureId1, ref string textureCoord1, ref string textureId2,
  1283. ref string textureCoord2, ref string blendingMode2, ref string textureId3,
  1284. ref string textureCoord3, ref string blendingMode3, ref string textureId4,
  1285. ref string textureCoord4, ref string blendingMode4 )
  1286. {
  1287. if( materialAttributeNode.ChildNodes.Count == 0 )
  1288. {
  1289. Error( "Parameter is not exists for matterial attribute \"{0}\".",
  1290. materialAttributeNode.Name );
  1291. return false;
  1292. }
  1293. int texturesCount = 0;
  1294. foreach( XmlNode parameterNode in materialAttributeNode.ChildNodes )
  1295. {
  1296. if( parameterNode.Name == "texture" )
  1297. {
  1298. string texCoord = XmlUtils.GetAttribute( parameterNode, "texcoord" );
  1299. string textureId = XmlUtils.GetAttribute( parameterNode, "texture" );
  1300. string blendingMode;
  1301. if( !ParseTextureBlendingMode( parameterNode, out blendingMode,
  1302. materialAttributeNode.Name ) )
  1303. return false;
  1304. switch( texturesCount )
  1305. {
  1306. case 0:
  1307. textureId1 = textureId;
  1308. textureCoord1 = texCoord;
  1309. break;
  1310. case 1:
  1311. textureId2 = textureId;
  1312. textureCoord2 = texCoord;
  1313. blendingMode2 = blendingMode;
  1314. break;
  1315. case 2:
  1316. textureId3 = textureId;
  1317. textureCoord3 = texCoord;
  1318. blendingMode3 = blendingMode;
  1319. break;
  1320. case 3:
  1321. textureId4 = textureId;
  1322. textureCoord4 = texCoord;
  1323. blendingMode4 = blendingMode;
  1324. break;
  1325. }
  1326. texturesCount++;
  1327. }
  1328. if( parameterNode.Name == "color" )
  1329. color = ConvertStringToColorValue( parameterNode.InnerText );
  1330. }
  1331. return true;
  1332. }
  1333. string GetTextureFileName( XmlNode profileNode, string imageId )
  1334. {
  1335. string textureFileName;
  1336. //XSI specified
  1337. foreach( XmlNode newParamNode in profileNode )
  1338. {
  1339. if( newParamNode.Name != "newparam" )
  1340. continue;
  1341. if( XmlUtils.GetAttribute( newParamNode, "sid" ) == imageId )
  1342. {
  1343. XmlNode sampler2D = XmlUtils.FindChildNode( newParamNode, "sampler2D" );
  1344. if( sampler2D == null )
  1345. continue;
  1346. XmlNode source = XmlUtils.FindChildNode( sampler2D, "source" );
  1347. if( source == null )
  1348. continue;
  1349. string surfaceId = source.InnerText;
  1350. foreach( XmlNode newParamSurfaceNode in profileNode )
  1351. {
  1352. if( newParamNode.Name != "newparam" )
  1353. continue;
  1354. if( XmlUtils.GetAttribute( newParamSurfaceNode, "sid" ) == surfaceId )
  1355. {
  1356. XmlNode surface = XmlUtils.FindChildNode( newParamSurfaceNode, "surface" );
  1357. if( surface == null )
  1358. continue;
  1359. XmlNode initFrom = XmlUtils.FindChildNode( surface, "init_from" );
  1360. if( initFrom == null )
  1361. continue;
  1362. if( generatedImages.TryGetValue( initFrom.InnerText, out textureFileName ) )
  1363. return textureFileName;
  1364. }
  1365. }
  1366. }
  1367. }
  1368. //Max\Maya specified
  1369. if( generatedImages.TryGetValue( imageId, out textureFileName ) )
  1370. return textureFileName;
  1371. return "";
  1372. }
  1373. bool ParseEffectNode( XmlNode profileNode, XmlNode effectNode, ref MySceneMaterial material )
  1374. {
  1375. foreach( XmlNode materialAttributeNode in effectNode.ChildNodes )
  1376. {
  1377. if( materialAttributeNode.Name == "diffuse" )
  1378. {
  1379. ColorValue diffuseColor = new ColorValue( 1, 1, 1 );
  1380. string textureId1 = "";
  1381. string textureId2 = "";
  1382. string textureId3 = "";
  1383. string textureId4 = "";
  1384. string textureCoord1 = "";
  1385. string textureCoord2 = "";
  1386. string textureCoord3 = "";
  1387. string textureCoord4 = "";
  1388. string blendingMode2 = "";
  1389. string blendingMode3 = "";
  1390. string blendingMode4 = "";
  1391. if( !ParseEffectAttribute( materialAttributeNode, ref diffuseColor, ref textureId1,
  1392. ref textureCoord1, ref textureId2, ref textureCoord2, ref blendingMode2,
  1393. ref textureId3, ref textureCoord3, ref blendingMode3, ref textureId4,
  1394. ref textureCoord4, ref blendingMode4 ) )
  1395. return false;
  1396. material.DiffuseColor = diffuseColor;
  1397. if( !string.IsNullOrEmpty( textureId1 ) )
  1398. {
  1399. material.Diffuse1Map = GetTextureFileName( profileNode, textureId1 );
  1400. material.Diffuse1TexCoord = textureCoord1;
  1401. }
  1402. if( !string.IsNullOrEmpty( textureId2 ) )
  1403. {
  1404. material.Diffuse2Map = GetTextureFileName( profileNode, textureId2 );
  1405. material.Diffuse2TexCoord = textureCoord2;
  1406. material.Diffuse2MapBlending = blendingMode2;
  1407. }
  1408. if( !string.IsNullOrEmpty( textureId3 ) )
  1409. {
  1410. material.Diffuse3Map = GetTextureFileName( profileNode, textureId3 );
  1411. material.Diffuse3TexCoord = textureCoord3;
  1412. material.Diffuse3MapBlending = blendingMode3;
  1413. }
  1414. if( !string.IsNullOrEmpty( textureId4 ) )
  1415. {
  1416. material.Diffuse4Map = GetTextureFileName( profileNode, textureId4 );
  1417. material.Diffuse4TexCoord = textureCoord4;
  1418. material.Diffuse4MapBlending = blendingMode4;
  1419. }
  1420. }
  1421. if( materialAttributeNode.Name == "specular" )
  1422. {
  1423. ColorValue specularColor = new ColorValue( 0, 0, 0 );
  1424. string textureId1 = "";
  1425. string textureId2 = "";
  1426. string textureId3 = "";
  1427. string textureId4 = "";
  1428. string textureCoord1 = "";
  1429. string textureCoord2 = "";
  1430. string textureCoord3 = "";
  1431. string textureCoord4 = "";
  1432. string blendingMode2 = "";
  1433. string blendingMode3 = "";
  1434. string blendingMode4 = "";
  1435. if( !ParseEffectAttribute( materialAttributeNode, ref specularColor, ref textureId1,
  1436. ref textureCoord1, ref textureId2, ref textureCoord2, ref blendingMode2,
  1437. ref textureId3, ref textureCoord3, ref blendingMode3, ref textureId4,
  1438. ref textureCoord4, ref blendingMode4 ) )
  1439. return false;
  1440. material.SpecularColor = specularColor;
  1441. if( !string.IsNullOrEmpty( textureId1 ) )
  1442. {
  1443. material.SpecularMap = GetTextureFileName( profileNode, textureId1 );
  1444. material.SpecularTexCoord = textureCoord1;
  1445. }
  1446. }
  1447. if( materialAttributeNode.Name == "shininess" )
  1448. {
  1449. XmlNode floatNode = XmlUtils.FindChildNode( materialAttributeNode, "float" );
  1450. if( floatNode == null )
  1451. {
  1452. Error( "\"float\" node is not exists for material attribute \"{0}\".",
  1453. materialAttributeNode.Name );
  1454. return false;
  1455. }
  1456. float shininess;
  1457. if( !float.TryParse( floatNode.InnerText, out shininess ) )
  1458. {
  1459. Error( "Invalid \"float\" attribute of \"shininess\" node." );
  1460. return false;
  1461. }
  1462. material.Shininess = shininess;
  1463. }
  1464. if( materialAttributeNode.Name == "emission" )
  1465. {
  1466. ColorValue emissionColor = new ColorValue( 0, 0, 0 );
  1467. string textureId1 = "";
  1468. string textureId2 = "";
  1469. string textureId3 = "";
  1470. string textureId4 = "";
  1471. string textureCoord1 = "";
  1472. string textureCoord2 = "";
  1473. string textureCoord3 = "";
  1474. string textureCoord4 = "";
  1475. string blendingMode2 = "";
  1476. string blendingMode3 = "";
  1477. string blendingMode4 = "";
  1478. if( !ParseEffectAttribute( materialAttributeNode, ref emissionColor, ref textureId1,
  1479. ref textureCoord1, ref textureId2, ref textureCoord2, ref blendingMode2,
  1480. ref textureId3, ref textureCoord3, ref blendingMode3, ref textureId4,
  1481. ref textureCoord4, ref blendingMode4 ) )
  1482. return false;
  1483. material.EmissionColor = emissionColor;
  1484. if( !string.IsNullOrEmpty( textureId1 ) )
  1485. {
  1486. material.EmissionMap = GetTextureFileName( profileNode, textureId1 );
  1487. material.EmissionTexCoord = textureCoord1;
  1488. }
  1489. }
  1490. if( materialAttributeNode.Name == "transparent" )
  1491. {
  1492. string opaque = XmlUtils.GetAttribute( materialAttributeNode, "opaque" );
  1493. if( opaque == "RGB_ZERO" )
  1494. {
  1495. material.Opaque = true;
  1496. }
  1497. XmlNode colorNode = XmlUtils.FindChildNode( materialAttributeNode, "color" );
  1498. if( colorNode == null )
  1499. {
  1500. material.TransparentColor = new ColorValue( 1, 1, 1 );
  1501. }
  1502. else
  1503. {
  1504. material.TransparentColor = ConvertStringToColorValue( colorNode.InnerText );
  1505. }
  1506. }
  1507. if( materialAttributeNode.Name == "transparency" )
  1508. {
  1509. XmlNode floatNode = XmlUtils.FindChildNode( materialAttributeNode, "float" );
  1510. if( floatNode == null )
  1511. {
  1512. Error( "\"float\" node is not exists for material attribute \"{0}\".",
  1513. materialAttributeNode.Name );
  1514. return false;
  1515. }
  1516. float transparency;
  1517. if( !float.TryParse( floatNode.InnerText, out transparency ) )
  1518. {
  1519. Error( "Invalid \"float\" attribute of \"transparency\" node." );
  1520. return false;
  1521. }
  1522. material.Transparency = transparency;
  1523. }
  1524. }
  1525. return true;
  1526. }
  1527. bool ParseEffectExtraNode( XmlNode extraNode, string effectId, ref MySceneMaterial material )
  1528. {
  1529. foreach( XmlNode extraAttributeNode in extraNode.ChildNodes )
  1530. {
  1531. if( extraAttributeNode.Name == "technique" )
  1532. {

Large files files are truncated, but you can click here to view the full file