private void ExportMeshBinding(Model model, string skelRef, MeshBinding meshBinding, List <geometry> geometries, List <controller> controllers, List <node> geomNodes) { var exporter = new ColladaMeshExporter(meshBinding.Mesh, Options); var mesh = exporter.Export(); var geom = new geometry(); geom.id = meshBinding.Mesh.Name + "-geom"; geom.name = meshBinding.Mesh.Name; geom.Item = mesh; geometries.Add(geom); bool hasSkin = skelRef != null && meshBinding.Mesh.IsSkinned(); skin skin = null; controller ctrl = null; if (hasSkin) { var boneNames = new Dictionary <string, Bone>(); foreach (var bone in model.Skeleton.Bones) { boneNames.Add(bone.Name, bone); } skin = ExportSkin(meshBinding.Mesh, model.Skeleton.Bones, boneNames, geom.id); ctrl = new controller(); ctrl.id = meshBinding.Mesh.Name + "-skin"; ctrl.name = meshBinding.Mesh.Name + "_Skin"; ctrl.Item = skin; controllers.Add(ctrl); } var geomNode = new node(); geomNode.id = geom.name + "-node"; geomNode.name = geom.name; geomNode.type = NodeType.NODE; if (hasSkin) { var controllerInstance = new instance_controller(); controllerInstance.url = "#" + ctrl.id; controllerInstance.skeleton = new string[] { "#" + skelRef }; geomNode.instance_controller = new instance_controller[] { controllerInstance }; } else { var geomInstance = new instance_geometry(); geomInstance.url = "#" + geom.id; geomNode.instance_geometry = new instance_geometry[] { geomInstance }; } geomNodes.Add(geomNode); }
private Model MakeDummyModel(Model original) { var newModel = new Model(); newModel.InitialPlacement = original.InitialPlacement; newModel.Name = original.Name; if (original.Skeleton != null) { var skeleton = Root.Skeletons.Where(skel => skel.Name == original.Skeleton.Name).FirstOrDefault(); if (skeleton == null) { string msg = String.Format("Model '{0}' references skeleton '{0}' that does not exist in the source file.", original.Name, original.Skeleton.Name); throw new ExportException(msg); } newModel.Skeleton = skeleton; } if (original.MeshBindings != null) { newModel.MeshBindings = new List <MeshBinding>(); foreach (var meshBinding in original.MeshBindings) { // Try to bind the original mesh, if it exists in the source file. // If it doesn't, generate a dummy mesh with 0 vertices var mesh = Root.Meshes.Where(m => m.Name == meshBinding.Mesh.Name).FirstOrDefault(); if (mesh == null) { mesh = GenerateDummyMesh(meshBinding); Root.Meshes.Add(mesh); } var binding = new MeshBinding(); binding.Mesh = mesh; newModel.MeshBindings.Add(binding); } } Root.Models.Add(newModel); return(newModel); }
private Mesh GenerateDummyMesh(MeshBinding meshBinding) { var vertexData = new VertexData(); vertexData.VertexComponentNames = meshBinding.Mesh.PrimaryVertexData.VertexComponentNames .Select(name => new GrannyString(name.String)).ToList(); vertexData.Vertices = new List <Vertex>(); var dummyVertex = meshBinding.Mesh.VertexFormat.CreateInstance(); vertexData.Vertices.Add(dummyVertex); Root.VertexDatas.Add(vertexData); var topology = new TriTopology(); topology.Groups = new List <TriTopologyGroup>(); var group = new TriTopologyGroup(); group.MaterialIndex = 0; group.TriCount = 0; group.TriFirst = 0; topology.Groups.Add(group); topology.Indices = new List <int>(); Root.TriTopologies.Add(topology); var mesh = new Mesh(); mesh.Name = meshBinding.Mesh.Name; mesh.VertexFormat = meshBinding.Mesh.VertexFormat; mesh.PrimaryTopology = topology; mesh.PrimaryVertexData = vertexData; if (meshBinding.Mesh.BoneBindings != null) { mesh.BoneBindings = new List <BoneBinding>(); ConformMeshBoneBindings(mesh, meshBinding.Mesh); } return(mesh); }
public Root Import(string inputPath) { var collada = COLLADA.Load(inputPath); var root = new Root(); root.ArtToolInfo = ImportArtToolInfo(collada); if (!Options.StripMetadata) { root.ExporterInfo = ImportExporterInfo(collada); } root.FromFileName = inputPath; root.Skeletons = new List <Skeleton>(); root.VertexDatas = new List <VertexData>(); root.TriTopologies = new List <TriTopology>(); root.Meshes = new List <Mesh>(); root.Models = new List <Model>(); root.TrackGroups = new List <TrackGroup>(); root.Animations = new List <Animation>(); ColladaGeometries = new Dictionary <string, Mesh>(); SkinnedMeshes = new HashSet <string>(); var collGeometries = new List <geometry>(); var collSkins = new List <skin>(); var collAnimations = new List <animation>(); var rootBones = new List <RootBoneInfo>(); // Import skinning controllers after skeleton and geometry loading has finished, as // we reference both of them during skin import foreach (var item in collada.Items) { if (item is library_controllers) { var controllers = item as library_controllers; if (controllers.controller != null) { foreach (var controller in controllers.controller) { if (controller.Item is skin) { collSkins.Add(controller.Item as skin); SkinnedMeshes.Add((controller.Item as skin).source1.Substring(1)); } else { Utils.Warn(String.Format("Controller {0} is unsupported and will be ignored", controller.Item.GetType().Name)); } } } } else if (item is library_visual_scenes) { var scenes = item as library_visual_scenes; if (scenes.visual_scene != null) { foreach (var scene in scenes.visual_scene) { if (scene.node != null) { foreach (var node in scene.node) { FindRootBones(new List <node>(), node, rootBones); } } } } } else if (item is library_geometries) { var geometries = item as library_geometries; if (geometries.geometry != null) { foreach (var geometry in geometries.geometry) { if (geometry.Item is mesh) { collGeometries.Add(geometry); } else { Utils.Warn(String.Format("Geometry type {0} is unsupported and will be ignored", geometry.Item.GetType().Name)); } } } } else if (item is library_animations) { var animations = item as library_animations; if (animations.animation != null) { collAnimations.AddRange(animations.animation); } } else { Utils.Warn(String.Format("Library {0} is unsupported and will be ignored", item.GetType().Name)); } } foreach (var bone in rootBones) { var skeleton = Skeleton.FromCollada(bone.Bone); var rootTransform = NodeHelpers.GetTransformHierarchy(bone.Parents); skeleton.TransformRoots(rootTransform.Inverted()); root.Skeletons.Add(skeleton); } foreach (var geometry in collGeometries) { VertexDescriptor vertexFormat = null; // Use the override vertex format, if one was specified Options.VertexFormats.TryGetValue(geometry.name, out vertexFormat); var mesh = ImportMesh(root, geometry.name, geometry, geometry.Item as mesh, vertexFormat); ColladaGeometries.Add(geometry.id, mesh); } // Import skinning controllers after skeleton and geometry loading has finished, as // we reference both of them during skin import if (rootBones.Count > 0) { foreach (var skin in collSkins) { ImportSkin(root, skin); } } if (collAnimations.Count > 0) { ImportAnimations(collAnimations, root, root.Skeletons.FirstOrDefault()); } var rootModel = new Model(); rootModel.Name = "Unnamed"; // TODO if (root.Skeletons.Count > 0) { rootModel.Skeleton = root.Skeletons[0]; rootModel.Name = rootModel.Skeleton.Bones[0].Name; } rootModel.InitialPlacement = new Transform(); rootModel.MeshBindings = new List <MeshBinding>(); foreach (var mesh in root.Meshes) { var binding = new MeshBinding(); binding.Mesh = mesh; rootModel.MeshBindings.Add(binding); } root.Models.Add(rootModel); // TODO: make this an option! if (root.Skeletons.Count > 0) { root.Skeletons[0].UpdateWorldTransforms(); } root.ZUp = ZUp; root.PostLoad(GR2.Header.DefaultTag); this.UpdateUserDefinedProperties(root); return(root); }
public void ImportFromCollada(string inputPath) { var collada = COLLADA.Load(inputPath); ImportArtToolInfo(collada); ImportExporterInfo(collada); FromFileName = inputPath; Skeletons = new List <Skeleton>(); VertexDatas = new List <VertexData>(); TriTopologies = new List <TriTopology>(); Meshes = new List <Mesh>(); Models = new List <Model>(); TrackGroups = new List <TrackGroup>(); Animations = new List <Animation>(); ColladaGeometries = new Dictionary <string, Mesh>(); SkinnedMeshes = new HashSet <string>(); var collGeometries = new List <geometry>(); var collSkins = new List <skin>(); var collAnimations = new List <animation>(); var rootBones = new List <node>(); // Import skinning controllers after skeleton and geometry loading has finished, as // we reference both of them during skin import foreach (var item in collada.Items) { if (item is library_controllers) { var controllers = item as library_controllers; if (controllers.controller != null) { foreach (var controller in controllers.controller) { if (controller.Item is skin) { collSkins.Add(controller.Item as skin); SkinnedMeshes.Add((controller.Item as skin).source1.Substring(1)); } else { Utils.Warn(String.Format("Controller {0} is unsupported and will be ignored", controller.Item.GetType().Name)); } } } } else if (item is library_visual_scenes) { var scenes = item as library_visual_scenes; if (scenes.visual_scene != null) { foreach (var scene in scenes.visual_scene) { foreach (var node in scene.node) { FindRootBones(null, node, rootBones); } } } } else if (item is library_geometries) { var geometries = item as library_geometries; if (geometries.geometry != null) { foreach (var geometry in geometries.geometry) { if (geometry.Item is mesh) { collGeometries.Add(geometry); } else { Utils.Warn(String.Format("Geometry type {0} is unsupported and will be ignored", geometry.Item.GetType().Name)); } } } } else if (item is library_animations) { var animations = item as library_animations; if (animations.animation != null) { collAnimations.AddRange(animations.animation); } } else { Utils.Warn(String.Format("Library {0} is unsupported and will be ignored", item.GetType().Name)); } } foreach (var bone in rootBones) { var skeleton = Skeleton.FromCollada(bone); Skeletons.Add(skeleton); } foreach (var geometry in collGeometries) { var mesh = ImportMesh(geometry.name, geometry.Item as mesh, FindVertexFormat(geometry)); ColladaGeometries.Add(geometry.id, mesh); } // Import skinning controllers after skeleton and geometry loading has finished, as // we reference both of them during skin import foreach (var skin in collSkins) { ImportSkin(skin); } if (collAnimations.Count > 0) { ImportAnimations(collAnimations); } var rootModel = new Model(); rootModel.Name = "Unnamed"; // TODO if (Skeletons.Count > 0) { rootModel.Skeleton = Skeletons[0]; rootModel.Name = rootModel.Skeleton.Bones[0].Name; } rootModel.InitialPlacement = new Transform(); rootModel.MeshBindings = new List <MeshBinding>(); foreach (var mesh in Meshes) { var binding = new MeshBinding(); binding.Mesh = mesh; rootModel.MeshBindings.Add(binding); } Models.Add(rootModel); // TODO: make this an option! if (Skeletons.Count > 0) { Skeletons[0].UpdateInverseWorldTransforms(); } PostLoad(); }
private Model MakeDummyModel(Model original) { var newModel = new Model(); newModel.InitialPlacement = original.InitialPlacement; newModel.Name = original.Name; if (original.Skeleton != null) { var skeleton = Root.Skeletons.Where(skel => skel.Name == original.Skeleton.Name).FirstOrDefault(); if (skeleton == null) { string msg = String.Format("Model '{0}' references skeleton '{0}' that does not exist in the source file.", original.Name, original.Skeleton.Name); throw new ExportException(msg); } newModel.Skeleton = skeleton; } if (original.MeshBindings != null) { newModel.MeshBindings = new List<MeshBinding>(); foreach (var meshBinding in original.MeshBindings) { // Try to bind the original mesh, if it exists in the source file. // If it doesn't, generate a dummy mesh with 0 vertices var mesh = Root.Meshes.Where(m => m.Name == meshBinding.Mesh.Name).FirstOrDefault(); if (mesh == null) { mesh = GenerateDummyMesh(meshBinding); Root.Meshes.Add(mesh); } var binding = new MeshBinding(); binding.Mesh = mesh; newModel.MeshBindings.Add(binding); } } Root.Models.Add(newModel); return newModel; }
private Mesh GenerateDummyMesh(MeshBinding meshBinding) { var vertexData = new VertexData(); vertexData.VertexComponentNames = meshBinding.Mesh.PrimaryVertexData.VertexComponentNames .Select(name => new GrannyString(name.String)).ToList(); vertexData.Vertices = new List<Vertex>(); var dummyVertex = Helpers.CreateInstance(meshBinding.Mesh.VertexFormat) as Vertex; vertexData.Vertices.Add(dummyVertex); Root.VertexDatas.Add(vertexData); var topology = new TriTopology(); topology.Groups = new List<TriTopologyGroup>(); var group = new TriTopologyGroup(); group.MaterialIndex = 0; group.TriCount = 0; group.TriFirst = 0; topology.Groups.Add(group); topology.Indices = new List<int>(); Root.TriTopologies.Add(topology); var mesh = new Mesh(); mesh.Name = meshBinding.Mesh.Name; mesh.VertexFormat = meshBinding.Mesh.VertexFormat; mesh.PrimaryTopology = topology; mesh.PrimaryVertexData = vertexData; if (meshBinding.Mesh.BoneBindings != null) { mesh.BoneBindings = new List<BoneBinding>(); ConformMeshBoneBindings(mesh, meshBinding.Mesh); } return mesh; }