/// <summary> /// Convert from FBX /// </summary> /// <param name="_Scene"></param> public Scene( FBX.Scene.Scene _Scene ) { // Create materials FBX.Scene.Materials.MaterialParameters[] SourceMaterials = _Scene.MaterialParameters; foreach ( FBX.Scene.Materials.MaterialParameters SourceMaterial in SourceMaterials ) m_Materials.Add( new Material( SourceMaterial, MapMaterial ) ); // Create nodes if ( _Scene.RootNode != null ) m_RootNode = new Node( this, _Scene.RootNode ); }
private void Read( ) { string[] data = new string[0]; #region "File reading" if (this.content != null) { data = this.content.Split(new char[] { '\n' }); } else { string path = this.setting.paths.urlModels + this.setting.paths.filename + ".fbx"; if (System.IO.File.Exists(path)) { this.setting.Status = FBXStatus.Loading; data = System.IO.File.ReadAllLines(path); } else { this.setting.Status = FBXStatus.FileNotFound; _isDone = true; this._isRunning = false; return; } } list.AddRange(data); #endregion #region "FBX SDK" this.fbxsdk = list[0].GetSDK(); if (this.fbxsdk == FBX.SDKNone) { this.setting.Status = FBXStatus.FBXSDKNotSupported; _isDone = true; this._isRunning = false; return; } else if (this.fbxsdk == FBX.SDKBinary) { this.setting.Status = FBXStatus.BinaryNotSupported; _isDone = true; this._isRunning = false; return; } #endregion foo = list.FindIndex(x => x == "Connections: {"); this.connectionListCount = this.GetListCount() - foo; this.IsRunning = false; }
/* * static Primitives() * { * Load(); * } */ /// <summary> /// Loads primitive geometry. /// </summary> internal static void Load() { var primitiveStream = ContentProvider.DownloadStream("internal://content/meshes/primitives.fbx").Result; var primitives = FBX.Import(primitiveStream, new FBX.ImportSettings { MergeMeshes = false, NormalImportMethod = FBX.NormalImportMethod.ImportNormals, }, "fbx", "primitives"); CubeGeometry = primitives.Meshes["Cube_Main"]; ConeGeometry = primitives.Meshes["Cone_Main"]; WedgeGeometry = primitives.Meshes["Wedge_Main"]; SphereGeometry = primitives.Meshes["Sphere_Main"]; CylinderGeometry = primitives.Meshes["Cylinder_Main"]; PlaneGeometry = primitives.Meshes["Plane_Main"]; _primitivesLoaded = true; }
public static FBX GetSDK(this string str_line) { FBX sdk = FBX.SDKNone; if (str_line.Contains("FBX Binary")) { #if UNITY_EDITOR Debug.LogWarning("Binary format not supported"); #endif sdk = FBX.SDKBinary; return(sdk); } else { string s = str_line.Substring(6, 5); switch (s) { case "6.1.0": sdk = FBX.SDK2010; break; case "7.1.0": sdk = FBX.SDK2011; break; case "7.2.0": sdk = FBX.SDK2012; break; case "7.3.0": sdk = FBX.SDK2013; break; case "7.4.0": sdk = FBX.SDK2014; break; case "7.5.0": sdk = FBX.SDK2015; break; case "7.6.0": sdk = FBX.SDK2016; break; default: sdk = FBX.SDKUnknown; #if UNITY_EDITOR Debug.LogWarning("Version not supported"); #endif break; } return(sdk); } }
/// <summary> /// Converts a FBX file into a temp scene representation (which may already contain meshes and materials, don't care) /// </summary> /// <param name="_FileName">The name of the FBX file to load</param> /// <param name="_Scene">The cirrus scene into which we should store the data</param> /// <param name="_ScaleFactor">The scale factor to apply to the entire scene /// By default, internal MAX units can be considered as centimeters so if you create a scene whose dimensions of a one meter box are 100x100x100, you /// will want to use a scale factor of 0.01. /// FBX offers the possibility of scaling but does a shitty job at it as it doesn't even rescale other dimensions like near/far clips or ranges for lights /// and camera, which plain sucks.</param> /// <param name="_Materials">An optional materials database containing informations about materials required by the scene</param> public void Load( FileInfo _FileName, FBX.Scene.Scene _Scene, float _ScaleFactor, MaterialsDatabase _Materials ) { if ( _FileName == null ) throw new Exception( "Invalid file name!" ); if ( !_FileName.Exists ) throw new Exception( "Scene file \"" + _FileName + "\" does not exist!" ); if ( _Scene == null ) throw new Exception( "Invalid Scene to load into!" ); m_Scene = _Scene; m_TempMesh2FinalMesh.Clear(); m_ScaleFactor = _ScaleFactor; m_MaterialsDatabase = _Materials; FBXImporter.Scene FBXScene = null; try { FBXScene = new FBXImporter.Scene(); FBXScene.Load( _FileName.FullName ); // Process materials ProcessMaterials( FBXScene.Materials ); // Process the scene nodes RecurseProcessNode( FBXScene.RootNode, null ); // Attach camera & light targets PostProcessNodes( m_Scene.RootNode ); // Build actual optimized and consolidated meshes BuildConsolidatedMeshes(); // Propagate state once so Local2World matrices are up to date m_Scene.RootNode.PropagateState(); } catch ( Exception _e ) { throw new Exception( "An error occurred while importing the FBX file \"" + _FileName + "\"!", _e ); } finally { FBXScene.Dispose(); } }
/// <summary> /// Loads a FBX file into a temp scene representation (which may already contain meshes and materials, don't care) /// </summary> /// <param name="_FileName">The name of the FBX file to load</param> /// <param name="_Scene">The cirrus scene into which we should store the data</param> public void Load( FileInfo _FileName, FBX.Scene.Scene _Scene ) { Load( _FileName, _Scene, 1.0f, null ); }
public override Asset Import(string path) { FBX fbx = FBX.Load(path); Model model = new Model(); Dictionary <long, object> components = new Dictionary <long, object>(); Dictionary <long, Matrix4> transforms = new Dictionary <long, Matrix4>(); Dictionary <long, string> triangulationErrors = new Dictionary <long, string>(); string name = Path.GetFileNameWithoutExtension(path); if (fbx == null) { SceneManager.Current.RaiseError(string.Format("File \"{0}\" could not be opened. Please ensure this is a binary FBX file.", name)); return(null); } var objects = fbx.Elements.Find(e => e.ID == "Objects"); RotationOrder order; var worldMatrix = createTransformFor(fbx.Elements.Find(e => e.ID == "GlobalSettings").Children[1], out order); foreach (var material in objects.Children.Where(e => e.ID == "Material")) { string matName = material.Properties[1].Value.ToString(); matName = matName.Substring(0, matName.IndexOf("::")); var m = new Material { Name = matName }; components.Add((long)material.Properties[0].Value, m); Console.WriteLine("Added material \"{0}\" ({1})", matName, material.Properties[0].Value); } var textures = objects.Children.Where(e => e.ID == "Texture"); foreach (var texture in textures) { Texture t = null; string fullFile = texture.Children.Find(e => e.ID == "FileName").Properties[0].Value.ToString(); if (fullFile.IndexOf('.') == -1) { continue; } string file = Path.GetFileName(fullFile); switch (Path.GetExtension(file)) { case ".bmp": t = SceneManager.Current.Content.Load <Texture, BMPImporter>(Path.GetFileNameWithoutExtension(file)); break; case ".png": t = SceneManager.Current.Content.Load <Texture, PNGImporter>(Path.GetFileNameWithoutExtension(file)); break; case ".tif": t = SceneManager.Current.Content.Load <Texture, TIFImporter>(Path.GetFileNameWithoutExtension(file)); break; case ".tga": t = SceneManager.Current.Content.Load <Texture, TGAImporter>(Path.GetFileNameWithoutExtension(file)); break; default: t = new Texture(); break; } if (!components.ContainsKey((long)texture.Properties[0].Value)) { components.Add((long)texture.Properties[0].Value, t); Console.WriteLine("Added texture \"{0}\" ({1})", file, texture.Properties[0].Value); } } foreach (var element in objects.Children.Where(e => e.ID == "Model")) { string modelName = element.Properties[1].Value.ToString(); modelName = modelName.Substring(0, modelName.IndexOf("::")); components.Add((long)element.Properties[0].Value, new ModelMesh { Name = modelName, Tag = (long)element.Properties[0].Value }); Console.WriteLine("Added model \"{0}\" ({1})", modelName, element.Properties[0].Value); var properties = element.Children.Find(c => c.ID == "Properties70"); var m = Matrix4.Identity; bool bRotationActive = false; var lclTranslation = OpenTK.Vector3.Zero; var lclRotation = Quaternion.Identity; var preRotation = Quaternion.Identity; var postRotation = Quaternion.Identity; var rotationPivot = OpenTK.Vector3.Zero; var rotationOffset = OpenTK.Vector3.Zero; var lclScaling = OpenTK.Vector3.One; var scalingPivot = OpenTK.Vector3.Zero; var scalingOffset = OpenTK.Vector3.Zero; var geoPosition = OpenTK.Vector3.Zero; var geoRotation = Quaternion.Identity; var geoScale = OpenTK.Vector3.One; FBXElem property; property = properties.Children.GetProperty("RotationActive"); if (property != null) { bRotationActive = ((int)property.Properties[4].Value == 1); } property = properties.Children.GetProperty("ScalingPivot"); if (property != null) { scalingPivot = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("Lcl Scaling"); if (property != null) { lclScaling = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("ScalingOffset"); if (property != null) { scalingOffset = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("RotationPivot"); if (property != null) { rotationPivot = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("PostRotation"); if (property != null) { postRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("Lcl Rotation"); if (property != null) { lclRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("PreRotation"); if (property != null) { preRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("RotationOffset"); if (property != null) { rotationOffset = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("Lcl Translation"); if (property != null) { lclTranslation = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("GeometricTranslation"); if (property != null) { geoPosition = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("GeometricRotation"); if (property != null) { geoRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("GeometricScaling"); if (property != null) { geoScale = new OpenTK.Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } m = Matrix4.CreateTranslation(scalingPivot).Inverted() * Matrix4.CreateScale(lclScaling) * Matrix4.CreateTranslation(scalingPivot) * Matrix4.CreateTranslation(scalingOffset) * Matrix4.CreateTranslation(rotationPivot).Inverted() * Matrix4.CreateFromQuaternion(postRotation) * Matrix4.CreateFromQuaternion(lclRotation) * Matrix4.CreateFromQuaternion(preRotation) * Matrix4.CreateTranslation(rotationPivot) * Matrix4.CreateTranslation(rotationOffset) * Matrix4.CreateTranslation(lclTranslation); if (m != Matrix4.Identity) { transforms.Add((long)element.Properties[0].Value, m); } } foreach (var element in objects.Children.Where(e => e.ID == "Geometry")) { bool bUVs = true; bool bNorms = true; bool bColours = true; bool bUseIndexNorm = false; bool bNeedsTriangulating = false; string geometryName = element.Properties[1].Value.ToString(); geometryName = geometryName.Substring(0, geometryName.IndexOf("::")); var verts = new List <OpenTK.Vector3>(); var norms = new List <OpenTK.Vector3>(); var uvs = new List <OpenTK.Vector2>(); var colours = new List <OpenTK.Graphics.Color4>(); var vertParts = (double[])element.Children.Find(e => e.ID == "Vertices").Properties[0].Value; for (int i = 0; i < vertParts.Length; i += 3) { verts.Add(new OpenTK.Vector3((float)vertParts[i + 0], (float)vertParts[i + 1], (float)vertParts[i + 2])); } SceneManager.Current.UpdateProgress(string.Format("Processed {0}->Vertices", element.Properties[1].Value)); var normElem = element.Children.Find(e => e.ID == "LayerElementNormal"); if (normElem != null) { var normParts = (double[])normElem.Children.Find(e => e.ID == "Normals").Properties[0].Value; for (int i = 0; i < normParts.Length; i += 3) { norms.Add(new OpenTK.Vector3((float)normParts[i + 0], (float)normParts[i + 1], (float)normParts[i + 2])); } bUseIndexNorm = (normElem.Children.Find(e => e.ID == "MappingInformationType").Properties[0].Value.ToString() == "ByVertice"); SceneManager.Current.UpdateProgress(string.Format("Processed {0}->Normals", element.Properties[1].Value)); } else { bNorms = false; } var colourElem = element.Children.Find(e => e.ID == "LayerElementColor"); if (colourElem != null) { var colourParts = (double[])colourElem.Children.Find(e => e.ID == "Colors").Properties[0].Value; var colourReferenceType = colourElem.Children.Find(e => e.ID == "ReferenceInformationType"); switch (colourReferenceType.Properties[0].Value.ToString()) { case "IndexToDirect": var colourIndicies = (int[])colourElem.Children.Find(e => e.ID == "ColorIndex").Properties[0].Value; for (int i = 0; i < colourIndicies.Length; i++) { int offset = colourIndicies[i] * 4; colours.Add(new OpenTK.Graphics.Color4((float)colourParts[offset + 0], (float)colourParts[offset + 1], (float)colourParts[offset + 2], (float)colourParts[offset + 3])); } break; case "Direct": bColours = false; break; default: throw new NotImplementedException("Unsupported Colour Reference Type: " + colourReferenceType.Properties[0].Value.ToString()); } SceneManager.Current.UpdateProgress(string.Format("Processed {0}->Colours", element.Properties[1].Value)); } else { bColours = false; } var uvElem = element.Children.Find(e => e.ID == "LayerElementUV"); if (uvElem != null) { var uvParts = (double[])uvElem.Children.Find(e => e.ID == "UV").Properties[0].Value; var uvReferenceType = uvElem.Children.Find(e => e.ID == "ReferenceInformationType"); if (uvReferenceType.Properties[0].Value.ToString() == "IndexToDirect") { var luvs = new List <OpenTK.Vector2>(); for (int i = 0; i < uvParts.Length; i += 2) { luvs.Add(new OpenTK.Vector2((float)uvParts[i + 0], 1 - (float)uvParts[i + 1])); } var uvindicies = (int[])uvElem.Children.Find(e => e.ID == "UVIndex").Properties[0].Value; for (int i = 0; i < uvindicies.Length; i++) { if (uvindicies[i] == -1) { uvs.Add(OpenTK.Vector2.Zero); } else { uvs.Add(luvs[uvindicies[i]]); } } } else { for (int i = 0; i < uvParts.Length; i += 2) { uvs.Add(new OpenTK.Vector2((float)uvParts[i + 0], (float)uvParts[i + 1])); } } SceneManager.Current.UpdateProgress(string.Format("Processed {0}->UVs", element.Properties[1].Value)); } else { bUVs = false; } var indicies = (int[])element.Children.Find(e => e.ID == "PolygonVertexIndex").Properties[0].Value; var faces = new List <FBXFace>(); var face = new FBXFace(); var j = 0; for (int i = 0; i < indicies.Length; i++) { bool bFace = false; int index = indicies[i]; if (index < 0) { bFace = true; index = (index * -1) - 1; } j++; face.AddVertex(verts[index], (bNorms ? norms[(bUseIndexNorm ? index : i)] : OpenTK.Vector3.Zero), (bUVs ? uvs[i] : OpenTK.Vector2.Zero), (bColours ? colours[i] : OpenTK.Graphics.Color4.White)); if (bFace) { if (j > 3) { triangulationErrors.Add((long)element.Properties[0].Value, geometryName); bNeedsTriangulating = true; break; } faces.Add(face); face = new FBXFace(); j = 0; } } var parts = new List <ModelMeshPart>(); if (!bNeedsTriangulating) { SceneManager.Current.UpdateProgress(string.Format("Processed {0}->Faces", element.Properties[1].Value)); var elemMaterial = element.Children.Find(e => e.ID == "LayerElementMaterial"); if (elemMaterial != null) { var faceMaterials = (int[])elemMaterial.Children.Find(e => e.ID == "Materials").Properties[0].Value; for (int i = 0; i < faceMaterials.Length; i++) { faces[i].MaterialID = faceMaterials[i]; } SceneManager.Current.UpdateProgress(string.Format("Processed {0}->Materials", element.Properties[1].Value)); } var materialGroups = faces.GroupBy(f => f.MaterialID); int processedFaceCount = 0, processedGroupCount = 0; foreach (var materialGroup in materialGroups) { var smoothingGroups = materialGroup.GroupBy(f => f.SmoothingGroup); foreach (var smoothingGroup in smoothingGroups) { var meshpart = new ModelMeshPart { PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.Triangles }; processedFaceCount = 0; foreach (var groupface in smoothingGroup) { foreach (var vert in groupface.Vertices) { meshpart.AddVertex(vert.Position, vert.Normal, vert.UV, vert.Colour); } processedFaceCount++; if (processedFaceCount % 250 == 0) { SceneManager.Current.UpdateProgress(string.Format("Processed {0}->MeshPart[{1}]->Face[{2}]", element.Properties[1].Value, processedGroupCount, processedFaceCount)); } } meshpart.Key = materialGroup.Key; parts.Add(meshpart); SceneManager.Current.UpdateProgress(string.Format("Processed {0}->MeshPart", element.Properties[1].Value)); processedGroupCount++; } } } components.Add((long)element.Properties[0].Value, parts); SceneManager.Current.UpdateProgress(string.Format("Processed {0}", element.Properties[1].Value)); } string[] connectionOrder = new string[] { "System.Collections.Generic.List`1[Flummery.ModelMeshPart]", "Flummery.Texture", "Flummery.Material", "Flummery.ModelMesh" }; var connections = fbx.Elements.Find(e => e.ID == "Connections"); HashSet <long> loaded = new HashSet <long>(); foreach (var connectionType in connectionOrder) { var connectionsOfType = connections.Children.Where(c => components.ContainsKey((long)c.Properties[1].Value) && components[(long)c.Properties[1].Value].GetType().ToString() == connectionType); foreach (var connection in connectionsOfType) { long keyA = (long)connection.Properties[1].Value; long keyB = (long)connection.Properties[2].Value; Console.WriteLine("{0} is connected to {1} :: {2}", keyA, keyB, connectionType); switch (connectionType) { case "Flummery.ModelMesh": int boneID; if (keyB == 0) { boneID = model.AddMesh((ModelMesh)components[keyA]); model.SetName(((ModelMesh)components[keyA]).Name, boneID); if (transforms.ContainsKey(keyA)) { model.SetTransform(transforms[keyA], boneID); } } else { var parent = model.FindMesh(keyB); if (parent != null) { boneID = model.AddMesh((ModelMesh)components[keyA], parent.Parent.Index); model.SetName(((ModelMesh)components[keyA]).Name, boneID); if (transforms.ContainsKey(keyA)) { model.SetTransform(transforms[keyA], boneID); } } else { if (!components.ContainsKey(keyB)) { Console.WriteLine("Components doesn't contain {0}", keyB); } else { Console.WriteLine("Couldn't find {0}", ((ModelMesh)components[keyB]).Name); } } } break; case "Flummery.Texture": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.Material") { if (loaded.Add(keyB)) { ((Material)components[keyB]).Texture = (Texture)components[keyA]; SceneManager.Current.Add((Material)components[keyB]); } } else { Console.WriteLine("{0} is of unknown type {1}", keyA, components[keyA].GetType().ToString()); Console.WriteLine("{0} is of unknown type {1}", keyB, components[keyB].GetType().ToString()); } break; case "System.Collections.Generic.List`1[Flummery.ModelMeshPart]": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.ModelMesh") { if (triangulationErrors.ContainsKey(keyA)) { triangulationErrors[keyA] += " (geometry of " + ((ModelMesh)components[keyB]).Name + ")"; } foreach (var part in (List <ModelMeshPart>)components[keyA]) { ((ModelMesh)components[keyB]).AddModelMeshPart(part); } } break; case "Flummery.Material": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.ModelMesh") { var materialLookup = connections.Children.Where(c => (long)c.Properties[2].Value == keyB).ToList(); for (int i = materialLookup.Count - 1; i > -1; i--) { if (!connectionsOfType.Any(c => (long)c.Properties[1].Value == (long)materialLookup[i].Properties[1].Value)) { materialLookup.RemoveAt(i); } } foreach (var part in ((ModelMesh)components[keyB]).MeshParts) { if ((long)materialLookup[(int)part.Key].Properties[1].Value == keyA) { part.Material = (Material)components[keyA]; //SceneManager.Current.Add(part.Material); } } } break; default: Console.WriteLine("{0} is of unknown type {1}", keyA, components[keyA].GetType().ToString()); if (components.ContainsKey(keyB)) { Console.WriteLine("{0} is of unknown type {1}", keyB, components[keyB].GetType().ToString()); } Console.WriteLine("==="); break; } } } if (triangulationErrors.Count > 0) { SceneManager.Current.UpdateProgress(string.Format("Failed to load {0}", name)); string error = string.Format("File \"{0}\" has part{1} that need been triangulating! Please triangulate the following:", name, (triangulationErrors.Count > 1 ? "s" : "")); foreach (var kvp in triangulationErrors) { error += "\r\n" + kvp.Value; } SceneManager.Current.RaiseError(error); return(null); } else { SceneManager.Current.UpdateProgress(string.Format("Loaded {0}", name)); model.Santise(); if (worldMatrix != Matrix4.Identity) { ModelManipulator.Freeze(model, worldMatrix); } ModelManipulator.FlipAxis(model.Root.Mesh, Axis.X, true); return(model); } }
public override Asset Import(string path) { FBX fbx = FBX.Load(path); Model model = new Model(); Dictionary <long, object> components = new Dictionary <long, object>(); Dictionary <long, Matrix4D> transforms = new Dictionary <long, Matrix4D>(); Dictionary <long, string> triangulationErrors = new Dictionary <long, string>(); string name = Path.GetFileNameWithoutExtension(path); if (fbx == null) { SceneManager.Current.RaiseError($"File \"{name}\" could not be opened. Please ensure this is a binary FBX file."); return(null); } FBXElem objects = fbx.Elements.Find(e => e.ID == "Objects"); Matrix4D worldMatrix = createTransformFor(fbx.Elements.Find(e => e.ID == "GlobalSettings").Children[1], out Quaternion.RotationOrder order); foreach (FBXElem material in objects.Children.Where(e => e.ID == "Material")) { string matName = material.Properties[1].Value.ToString(); matName = matName.Substring(0, matName.IndexOf("::")); Material m = new Material { Name = matName }; components.Add((long)material.Properties[0].Value, m); Console.WriteLine($"Added material \"{matName}\" ({material.Properties[0].Value})"); } foreach (FBXElem video in objects.Children.Where(e => e.ID == "Video")) { FBXElem content = video.Children.Find(e => e.ID == "Content"); if (content.Properties[0].Size > 4) { components.Add((long)video.Properties[0].Value, (byte[])content.Properties[0].Value); } } IEnumerable <FBXElem> textures = objects.Children.Where(e => e.ID == "Texture"); foreach (FBXElem texture in textures) { string fullFile = texture.Children.Find(e => e.ID == "FileName").Properties[0].Value.ToString(); if (fullFile.IndexOf('.') == -1) { continue; } string file = Path.GetFileName(fullFile); Texture t = new Texture(); long videoKey = (long)fbx.Elements.Find(e => e.ID == "Connections").Children.Where(c => (long)c.Properties[2].Value == (long)texture.Properties[0].Value).First().Properties[1].Value; if (components.ContainsKey(videoKey)) { using (FileStream fs = new FileStream(Path.Combine(Path.GetDirectoryName(path), file), FileMode.Create)) using (BinaryWriter bw = new BinaryWriter(fs)) { bw.Write((byte[])components[videoKey]); } } t = SceneManager.Current.Content.Load(Path.GetFileName(file)); switch (fbx.Elements.Find(e => e.ID == "Connections").Children.Where(c => (long)c.Properties[1].Value == (long)texture.Properties[0].Value).First().Properties.Last().Value.ToString()) { case "NormalMap": t.Type = Texture.TextureType.Normal; break; case "SpecularColor": t.Type = Texture.TextureType.Specular; break; } if (!components.ContainsKey((long)texture.Properties[0].Value)) { components.Add((long)texture.Properties[0].Value, t); Console.WriteLine($"Added texture \"{file}\" ({texture.Properties[0].Value})"); } } foreach (FBXElem element in objects.Children.Where(e => e.ID == "Model")) { string modelName = element.Properties[1].Value.ToString(); modelName = modelName.Substring(0, modelName.IndexOf("::")); components.Add((long)element.Properties[0].Value, new ModelMesh { Name = modelName, Tag = (long)element.Properties[0].Value }); Console.WriteLine("Added model \"{0}\" ({1})", modelName, element.Properties[0].Value); FBXElem properties = element.Children.Find(c => c.ID == "Properties70"); Matrix4D m = Matrix4D.Identity; bool bRotationActive = false; Vector3 lclTranslation = Vector3.Zero; Quaternion lclRotation = Quaternion.Identity; Quaternion preRotation = Quaternion.Identity; Quaternion postRotation = Quaternion.Identity; Vector3 rotationPivot = Vector3.Zero; Vector3 rotationOffset = Vector3.Zero; Vector3 lclScaling = Vector3.One; Vector3 scalingPivot = Vector3.Zero; Vector3 scalingOffset = Vector3.Zero; Vector3 geoPosition = Vector3.Zero; Quaternion geoRotation = Quaternion.Identity; Vector3 geoScale = Vector3.One; FBXElem property; property = properties.Children.GetProperty("RotationActive"); if (property != null) { bRotationActive = ((int)property.Properties[4].Value == 1); } property = properties.Children.GetProperty("ScalingPivot"); if (property != null) { scalingPivot = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("Lcl Scaling"); if (property != null) { lclScaling = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("ScalingOffset"); if (property != null) { scalingOffset = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("RotationPivot"); if (property != null) { rotationPivot = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("PostRotation"); if (property != null) { postRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("Lcl Rotation"); if (property != null) { lclRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("PreRotation"); if (property != null) { preRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("RotationOffset"); if (property != null) { rotationOffset = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("Lcl Translation"); if (property != null) { lclTranslation = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("GeometricTranslation"); if (property != null) { geoPosition = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } property = properties.Children.GetProperty("GeometricRotation"); if (property != null) { geoRotation = MakeQuaternion( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value), order ); } property = properties.Children.GetProperty("GeometricScaling"); if (property != null) { geoScale = new Vector3( Convert.ToSingle(property.Properties[4].Value), Convert.ToSingle(property.Properties[5].Value), Convert.ToSingle(property.Properties[6].Value) ); } m = Matrix4D.CreateTranslation(scalingPivot).Inverted() * Matrix4D.CreateScale(lclScaling) * Matrix4D.CreateTranslation(scalingPivot) * Matrix4D.CreateTranslation(scalingOffset) * Matrix4D.CreateTranslation(rotationPivot).Inverted() * Matrix4D.CreateFromQuaternion(postRotation) * Matrix4D.CreateFromQuaternion(lclRotation) * Matrix4D.CreateFromQuaternion(preRotation) * Matrix4D.CreateTranslation(rotationPivot) * Matrix4D.CreateTranslation(rotationOffset) * Matrix4D.CreateTranslation(lclTranslation); if (m != Matrix4D.Identity) { transforms.Add((long)element.Properties[0].Value, m); } } foreach (FBXElem element in objects.Children.Where(e => e.ID == "Geometry")) { bool bUVs = true; bool bNorms = true; bool bColours = true; bool bUseIndexNorm = false; bool bNeedsTriangulating = false; string geometryName = element.Properties[1].Value.ToString(); geometryName = geometryName.Substring(0, geometryName.IndexOf("::")); List <Vector3> verts = new List <Vector3>(); List <Vector3> norms = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <Colour> colours = new List <Colour>(); double[] vertParts = (double[])element.Children.Find(e => e.ID == "Vertices").Properties[0].Value; for (int i = 0; i < vertParts.Length; i += 3) { verts.Add(new Vector3((float)vertParts[i + 0], (float)vertParts[i + 1], (float)vertParts[i + 2])); } SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->Vertices"); FBXElem normElem = element.Children.Find(e => e.ID == "LayerElementNormal"); if (normElem != null) { double[] normParts = (double[])normElem.Children.Find(e => e.ID == "Normals").Properties[0].Value; for (int i = 0; i < normParts.Length; i += 3) { norms.Add(new Vector3((float)normParts[i + 0], (float)normParts[i + 1], (float)normParts[i + 2])); } bUseIndexNorm = (normElem.Children.Find(e => e.ID == "MappingInformationType").Properties[0].Value.ToString() == "ByVertice"); SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->Normals"); } else { bNorms = false; } FBXElem colourElem = element.Children.Find(e => e.ID == "LayerElementColor"); if (colourElem != null) { double[] colourParts = (double[])colourElem.Children.Find(e => e.ID == "Colors").Properties[0].Value; FBXElem colourReferenceType = colourElem.Children.Find(e => e.ID == "ReferenceInformationType"); switch (colourReferenceType.Properties[0].Value.ToString()) { case "IndexToDirect": int[] colourIndicies = (int[])colourElem.Children.Find(e => e.ID == "ColorIndex").Properties[0].Value; for (int i = 0; i < colourIndicies.Length; i++) { int offset = colourIndicies[i] * 4; colours.Add(new Colour( (float)colourParts[offset + 0], (float)colourParts[offset + 1], (float)colourParts[offset + 2], (float)colourParts[offset + 3]) ); } break; case "Direct": bColours = false; break; default: throw new NotImplementedException($"Unsupported Colour Reference Type: {colourReferenceType.Properties[0].Value}"); } SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->Colours"); } else { bColours = false; } FBXElem uvElem = element.Children.Find(e => e.ID == "LayerElementUV"); if (uvElem != null) { double[] uvParts = (double[])uvElem.Children.Find(e => e.ID == "UV").Properties[0].Value; FBXElem uvReferenceType = uvElem.Children.Find(e => e.ID == "ReferenceInformationType"); if (uvReferenceType.Properties[0].Value.ToString() == "IndexToDirect") { List <Vector2> luvs = new List <Vector2>(); for (int i = 0; i < uvParts.Length; i += 2) { luvs.Add(new Vector2((float)uvParts[i + 0], 1 - (float)uvParts[i + 1])); } int[] uvindicies = (int[])uvElem.Children.Find(e => e.ID == "UVIndex").Properties[0].Value; for (int i = 0; i < uvindicies.Length; i++) { if (uvindicies[i] == -1) { uvs.Add(Vector2.Zero); } else { uvs.Add(luvs[uvindicies[i]]); } } } else { for (int i = 0; i < uvParts.Length; i += 2) { uvs.Add(new Vector2((float)uvParts[i + 0], (float)uvParts[i + 1])); } } SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->UVs"); } else { bUVs = false; } int[] indicies = (int[])element.Children.Find(e => e.ID == "PolygonVertexIndex").Properties[0].Value; List <FBXFace> faces = new List <FBXFace>(); FBXFace face = new FBXFace(); int j = 0; for (int i = 0; i < indicies.Length; i++) { bool bFace = false; int index = indicies[i]; if (index < 0) { bFace = true; index = (index * -1) - 1; } j++; face.AddVertex(verts[index], bNorms ? norms[bUseIndexNorm ? index : i] : Vector3.Zero, bUVs ? uvs[i] : Vector2.Zero, bColours ? colours[i] : Colour.White); if (bFace) { if (j > 3) { triangulationErrors.Add((long)element.Properties[0].Value, geometryName); bNeedsTriangulating = true; break; } faces.Add(face); face = new FBXFace(); j = 0; } } List <ModelMeshPart> parts = new List <ModelMeshPart>(); if (!bNeedsTriangulating) { SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->Faces"); FBXElem elemMaterial = element.Children.Find(e => e.ID == "LayerElementMaterial"); if (elemMaterial != null) { int[] faceMaterials = (int[])elemMaterial.Children.Find(e => e.ID == "Materials").Properties[0].Value; for (int i = 0; i < faceMaterials.Length; i++) { faces[i].MaterialID = faceMaterials[i]; } SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->Materials"); } IEnumerable <IGrouping <int, FBXFace> > materialGroups = faces.GroupBy(f => f.MaterialID); int processedFaceCount = 0, processedGroupCount = 0; foreach (IGrouping <int, FBXFace> materialGroup in materialGroups) { IEnumerable <IGrouping <int, FBXFace> > smoothingGroups = materialGroup.GroupBy(f => f.SmoothingGroup); foreach (IGrouping <int, FBXFace> smoothingGroup in smoothingGroups) { ModelMeshPart meshpart = new ModelMeshPart { PrimitiveType = Flummery.Core.PrimitiveType.Triangles }; processedFaceCount = 0; foreach (FBXFace groupface in smoothingGroup) { foreach (Vertex vert in groupface.Vertices) { meshpart.AddVertex(vert.Position, vert.Normal, vert.UV, vert.Colour); } processedFaceCount++; if (processedFaceCount % 250 == 0) { SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->MeshPart[{processedGroupCount}]->Face[{processedFaceCount}]"); } } meshpart.Key = materialGroup.Key; parts.Add(meshpart); SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}->MeshPart"); processedGroupCount++; } } } components.Add((long)element.Properties[0].Value, parts); SceneManager.Current.UpdateProgress($"Processed {element.Properties[1].Value}"); } Dictionary <long, BoneType> nodeAttributes = new Dictionary <long, BoneType>(); Dictionary <long, object> nodeAttachments = new Dictionary <long, object>(); foreach (FBXElem nodeAttribute in objects.Children.Where(e => e.ID == "NodeAttribute")) { FBXElem typeFlags = nodeAttribute.Children.Find(e => e.ID == "TypeFlags"); if (typeFlags != null) { switch (typeFlags.Properties[0].Value.ToString().ToLower()) { case "light": LIGHT light = new LIGHT(); FBXElem lightType = nodeAttribute.Children.Find(c => c.ID == "Properties70").Children.GetProperty("LightType"); light.Type = (LIGHT.LightType)(lightType == null ? 0 : lightType.Properties[4].Value); nodeAttributes.Add((long)nodeAttribute.Properties[0].Value, BoneType.Light); nodeAttachments.Add((long)nodeAttribute.Properties[0].Value, light); break; default: // null node break; } } } string[] connectionOrder = new string[] { "System.Collections.Generic.List`1[Flummery.Core.ModelMeshPart]", "Flummery.Core.Texture", "Flummery.Core.Material", "Flummery.Core.ModelMesh" }; FBXElem connections = fbx.Elements.Find(e => e.ID == "Connections"); HashSet <long> loaded = new HashSet <long>(); foreach (string connectionType in connectionOrder) { IEnumerable <FBXElem> connectionsOfType = connections.Children.Where(c => components.ContainsKey((long)c.Properties[1].Value) && components[(long)c.Properties[1].Value].GetType().ToString() == connectionType); foreach (FBXElem connection in connectionsOfType) { long keyA = (long)connection.Properties[1].Value; long keyB = (long)connection.Properties[2].Value; Console.WriteLine("{0} is connected to {1} :: {2}", keyA, keyB, connectionType); switch (connectionType) { case "Flummery.Core.ModelMesh": int boneID; if (keyB == 0) { boneID = model.AddMesh((ModelMesh)components[keyA]); model.SetName(((ModelMesh)components[keyA]).Name, boneID); if (transforms.ContainsKey(keyA)) { model.SetTransform(transforms[keyA], boneID); } FBXElem attribute = connections.Children.FirstOrDefault(c => nodeAttributes.ContainsKey((long)c.Properties[1].Value) && (long)c.Properties[2].Value == keyA); if (attribute != null) { keyA = (long)attribute.Properties[1].Value; if (nodeAttributes.ContainsKey(keyA)) { model.Bones[boneID].Type = nodeAttributes[keyA]; } if (nodeAttachments.ContainsKey(keyA)) { model.Bones[boneID].Attachment = nodeAttachments[keyA]; } } } else { ModelMesh parent = model.FindMesh(keyB); if (parent != null) { boneID = model.AddMesh((ModelMesh)components[keyA], parent.Parent.Index); model.SetName(((ModelMesh)components[keyA]).Name, boneID); if (transforms.ContainsKey(keyA)) { model.SetTransform(transforms[keyA], boneID); } } else { if (!components.ContainsKey(keyB)) { Console.WriteLine("Components doesn't contain {0}", keyB); } else { Console.WriteLine("Couldn't find {0}", ((ModelMesh)components[keyB]).Name); } } } break; case "Flummery.Core.Texture": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.Core.Material") { if (loaded.Add(keyA)) { ((Material)components[keyB]).Texture = (Texture)components[keyA]; //SceneManager.Current.Add((Material)components[keyB]); } } else { Console.WriteLine("{0} is of unknown type {1}", keyA, components[keyA].GetType().ToString()); Console.WriteLine("{0} is of unknown type {1}", keyB, components[keyB].GetType().ToString()); } break; case "System.Collections.Generic.List`1[Flummery.Core.ModelMeshPart]": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.Core.ModelMesh") { if (triangulationErrors.ContainsKey(keyA)) { triangulationErrors[keyA] += " (geometry of " + ((ModelMesh)components[keyB]).Name + ")"; } foreach (ModelMeshPart part in (List <ModelMeshPart>)components[keyA]) { ((ModelMesh)components[keyB]).AddModelMeshPart(part); } } break; case "Flummery.Core.Material": if (components.ContainsKey(keyB) && components[keyB].GetType().ToString() == "Flummery.Core.ModelMesh") { List <FBXElem> materialLookup = connections.Children.Where(c => (long)c.Properties[2].Value == keyB).ToList(); for (int i = materialLookup.Count - 1; i > -1; i--) { if (!connectionsOfType.Any(c => (long)c.Properties[1].Value == (long)materialLookup[i].Properties[1].Value)) { materialLookup.RemoveAt(i); } } foreach (ModelMeshPart part in ((ModelMesh)components[keyB]).MeshParts) { if ((long)materialLookup[(int)part.Key].Properties[1].Value == keyA) { part.Material = (Material)components[keyA]; SceneManager.Current.Add(part.Material); } } } break; default: Console.WriteLine("{0} is of unknown type {1}", keyA, components[keyA].GetType().ToString()); if (components.ContainsKey(keyB)) { Console.WriteLine("{0} is of unknown type {1}", keyB, components[keyB].GetType().ToString()); } Console.WriteLine("==="); break; } } } if (triangulationErrors.Count > 0) { SceneManager.Current.UpdateProgress($"Failed to load {name}"); string error = $"File \"{name}\" has part{(triangulationErrors.Count > 1 ? "s" : "")} that need been triangulating! Please triangulate the following:"; foreach (KeyValuePair <long, string> kvp in triangulationErrors) { error += $"\r\n{kvp.Value}"; } SceneManager.Current.RaiseError(error); return(null); } else { SceneManager.Current.UpdateProgress($"Loaded {name}"); model.Santise(); //if (worldMatrix != Matrix4D.Identity) { ModelManipulator.Freeze(model, worldMatrix); } ModelManipulator.FlipAxis(model, Axis.Z, true); return(model); } }
public Node( Scene _Owner, FBX.Scene.Nodes.Node _Node ) { m_Owner = _Owner; m_Owner.m_Nodes.Add( this ); if ( _Node is FBX.Scene.Nodes.Mesh ) m_Type = TYPE.MESH; else if ( _Node is FBX.Scene.Nodes.Camera ) m_Type = TYPE.CAMERA; else if ( _Node is FBX.Scene.Nodes.Light ) m_Type = TYPE.LIGHT; else { // Isolate locators as probes if ( _Node.Name.ToLower().IndexOf( "locator" ) != -1 ) m_Type = TYPE.PROBE; } m_Local2Parent.FromMatrix4( _Node.Local2Parent ); // Build children FBX.Scene.Nodes.Node[] Children = _Node.Children; m_Children = new Node[Children.Length]; for ( int ChildIndex=0; ChildIndex < Children.Length; ChildIndex++ ) { FBX.Scene.Nodes.Node SourceChild = Children[ChildIndex]; Node Child = null; switch ( SourceChild.NodeType ) { case FBX.Scene.Nodes.Node.NODE_TYPE.NODE: Child = new Node( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.LIGHT: Child = new Light( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.CAMERA: Child = new Camera( _Owner, SourceChild ); break; case FBX.Scene.Nodes.Node.NODE_TYPE.MESH: Child = new Mesh( _Owner, SourceChild ); break; } m_Children[ChildIndex] = Child; } }
public Primitive( Mesh _Owner, FBX.Scene.Nodes.Mesh.Primitive _Primitive ) { m_Owner = _Owner; m_MaterialID = (ushort) _Primitive.MaterialParms.ID; m_Faces = new Face[_Primitive.FacesCount]; m_Vertices = new Vertex[_Primitive.VerticesCount]; // Retrieve streams FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE[] Usages = { FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT, FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS, }; FBX.Scene.Nodes.Mesh.Primitive.VertexStream[][] Streams = new FBX.Scene.Nodes.Mesh.Primitive.VertexStream[Usages.Length][]; for ( int UsageIndex=0; UsageIndex < Usages.Length; UsageIndex++ ) { Streams[UsageIndex] = _Primitive.FindStreamsByUsage( Usages[UsageIndex] ); if ( Streams[UsageIndex].Length == 0 ) throw new Exception( "No stream for usage " + Usages[UsageIndex] + "! Can't complete target vertex format!" ); } // Build local space bounding box float3 Temp = new float3(); WMath.Vector[] VertexPositions = Streams[0][0].Content as WMath.Vector[]; foreach ( WMath.Vector VertexPosition in VertexPositions ) { Temp.FromVector3( VertexPosition ); m_BBoxMin.Min( Temp ); m_BBoxMax.Max( Temp ); } // Build faces int FaceIndex = 0; foreach ( FBX.Scene.Nodes.Mesh.Primitive.Face F in _Primitive.Faces ) { m_Faces[FaceIndex].V0 = F.V0; m_Faces[FaceIndex].V1 = F.V1; m_Faces[FaceIndex].V2 = F.V2; FaceIndex++; } // Build vertices for ( int VertexIndex=0; VertexIndex < m_Vertices.Length; VertexIndex++ ) { for ( int UsageIndex=0; UsageIndex < Usages.Length; UsageIndex++ ) { FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE Usage = Usages[UsageIndex]; switch ( Usage ) { case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.POSITION: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].P = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.NORMAL: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].N = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TANGENT: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].G = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.BITANGENT: { float3[] Stream = Streams[UsageIndex][0].Content as float3[]; m_Vertices[VertexIndex].B = Stream[VertexIndex]; break; } case FBX.Scene.Nodes.Mesh.Primitive.VertexStream.USAGE.TEXCOORDS: { float2[] Stream = Streams[UsageIndex][0].Content as float2[]; m_Vertices[VertexIndex].T = Stream[VertexIndex]; break; } } } } }
public Mesh( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Mesh _Mesh = _Node as FBX.Scene.Nodes.Mesh; m_Primitives = new Primitive[_Mesh.PrimitivesCount]; int PrimitiveIndex = 0; foreach ( FBX.Scene.Nodes.Mesh.Primitive SourcePrimitive in _Mesh.Primitives ) m_Primitives[PrimitiveIndex++] = new Primitive( this, SourcePrimitive ); }
public Material( FBX.Scene.Materials.MaterialParameters _SourceMaterial, MaterialMapperDelegate _Mapper ) { float3 Temp = new float3(); FBX.Scene.Materials.MaterialParameters.Parameter P = null; m_ID = (ushort) _SourceMaterial.ID; // Get diffuse color + texture ID P = _SourceMaterial.Find( "DiffuseColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_DiffuseColor = Temp; } P = _SourceMaterial.Find( "DiffuseTexture" ); m_DiffuseTextureID = _Mapper( P != null ? P.AsTexture2D : null ); // Get specular color + texture ID + exponent P = _SourceMaterial.Find( "SpecularColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_SpecularColor = Temp; } P = _SourceMaterial.Find( "SpecularTexture" ); m_SpecularTextureID = _Mapper( P != null ? P.AsTexture2D : null ); P = _SourceMaterial.Find( "SpecularExponent" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_SpecularExponent = Temp; } // Get noral map ID P = _SourceMaterial.Find( "NormalTexture" ); m_NormalTextureID = _Mapper( P != null ? P.AsTexture2D : null ); // Get emissive P = _SourceMaterial.Find( "EmissiveColor" ); if ( P != null ) { Temp.FromVector3( P.AsFloat3.Value ); m_EmissiveColor = Temp; } }
public Light( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Light _Light = _Node as FBX.Scene.Nodes.Light; m_LightType = (LIGHT_TYPE) _Light.Type; m_Color.FromVector3( _Light.Color ); m_Intensity = _Light.Intensity; m_HotSpot = _Light.HotSpot; m_ConeAngle = _Light.ConeAngle; }
public Camera( Scene _Owner, FBX.Scene.Nodes.Node _Node ) : base(_Owner, _Node) { FBX.Scene.Nodes.Camera _Camera = _Node as FBX.Scene.Nodes.Camera; m_FOV = _Camera.FOV; }
private ushort MapMaterial( FBX.Scene.Materials.MaterialParameters.ParameterTexture2D _Texture ) { if ( _Texture == null ) return (ushort) 0xFFFF; // if ( _Texture.Value.URL.IndexOf( "pata_diff_colo.tga" ) != -1 ) // return 0; return (ushort) _Texture.Value.ID; }