/// <summary> /// Returns the submesh for this face based on material info. /// </summary> /// <param name='f'>The face to find a submesh for.</param> public KeyValuePair <IntermediateMaterial, List <int> > FindOrCreateSubMesh(Face f) { ExternalReference externalRef = null; if (Header.Parent != null) { externalRef = Header.Parent as ExternalReference; } // Fetch palettes MaterialPalette mp = null; if (f.MaterialIndex != -1) { if (externalRef != null) { externalRef.Header.MaterialPalettes.TryGetValue(f.MaterialIndex, out mp); } if (mp == null) { Header.MaterialPalettes.TryGetValue(f.MaterialIndex, out mp); } if (mp == null) { Log.WriteError("Could not find material palette: " + f.MaterialIndex); } } TexturePalette mainTex = null; if (f.TexturePattern != -1) { if (externalRef != null) { externalRef.Header.TexturePalettes.TryGetValue(f.TexturePattern, out mainTex); } if (mainTex == null) { Header.TexturePalettes.TryGetValue(f.TexturePattern, out mainTex); } if (mainTex == null) { Log.WriteError("Could not find texture pattern: " + f.TexturePattern); } } TexturePalette detailTex = null; if (f.DetailTexturePattern != -1) { if (externalRef != null) { externalRef.Header.TexturePalettes.TryGetValue(f.DetailTexturePattern, out detailTex); } if (mainTex == null) { Header.TexturePalettes.TryGetValue(f.DetailTexturePattern, out detailTex); } if (mainTex == null) { Log.WriteError("Could not find detail texture pattern: " + f.DetailTexturePattern); } } // Check locally foreach (KeyValuePair <IntermediateMaterial, List <int> > mesh in SubMeshes) { if (mesh.Key.Equals(mp, mainTex, detailTex, f.Transparency, f.LightMode)) { return(mesh); } } // Create a new submesh IntermediateMaterial im = Header.MaterialBank.FindOrCreateMaterial(f); KeyValuePair <IntermediateMaterial, List <int> > newMesh = new KeyValuePair <IntermediateMaterial, List <int> >(im, new List <int>()); SubMeshes.Add(newMesh); return(newMesh); }
public override IntermediateModel Process(IntermediateModelDef input, ContentProcessorContext context) { Scale = Scale == 0.0f ? 1.0f : Scale; model = new IntermediateModel(); String prefix = context.OutputDirectory; String wholeName = context.OutputFilename; String partialName = wholeName.Substring(prefix.Length); String modelName = partialName.Replace("\\\\", "\\"); modelName = modelName.Replace(".xnb", "").Replace(".XNB", ""); // Get the custom data associated with the model model.CustomData = ProcessCustomData(context); var scaleCustomData = model.CustomData["Scale"]; if (scaleCustomData != null) { Scale = Convert.ToSingle(scaleCustomData.Value); } List <IntermediateModelMesh> imms = new List <IntermediateModelMesh>(); for (int i = 0; i < input.ModelMeshes.Count; ++i) { var modelMesh = input.ModelMeshes[i]; IntermediateModelMesh imm = new IntermediateModelMesh(); ModelMeshVertex[] vertices = new ModelMeshVertex[modelMesh.Vertices.Length]; WeightedVertex[] origVertices = new WeightedVertex[modelMesh.Vertices.Length]; //DebugNow(); for (int j = 0; j < modelMesh.Vertices.Length; ++j) { if (input.HasSkinningData) { var intermediateWeightedVertex = input.WeightedVertices[modelMesh.Vertices[j].WeightedVertexIndex]; vertices[j].Position = Vector3.Transform(intermediateWeightedVertex.Position.ToVector3(), Matrix.CreateScale(Scale)); origVertices[j].Weight0 = new Core.Graphics.Primitives.BoneWeight(); origVertices[j].Weight0.BoneIndex = intermediateWeightedVertex.JointWeights[0].JointIndex; origVertices[j].Weight0.Weight = intermediateWeightedVertex.JointWeights[0].Weight; origVertices[j].Weight1 = new Core.Graphics.Primitives.BoneWeight(); origVertices[j].Weight1.BoneIndex = intermediateWeightedVertex.JointWeights[1].JointIndex; origVertices[j].Weight1.Weight = intermediateWeightedVertex.JointWeights[1].Weight; origVertices[j].Weight2 = new Core.Graphics.Primitives.BoneWeight(); origVertices[j].Weight2.BoneIndex = intermediateWeightedVertex.JointWeights[2].JointIndex; origVertices[j].Weight2.Weight = intermediateWeightedVertex.JointWeights[2].Weight; origVertices[j].Weight3 = new Core.Graphics.Primitives.BoneWeight(); origVertices[j].Weight3.BoneIndex = intermediateWeightedVertex.JointWeights[3].JointIndex; origVertices[j].Weight3.Weight = intermediateWeightedVertex.JointWeights[3].Weight; } else { vertices[j].Position = Vector3.Transform(modelMesh.Vertices[j].Position.ToVector3(), Matrix.CreateScale(Scale)); } vertices[j].Normal = Vector3.TransformNormal(modelMesh.Vertices[j].Normal.ToVector3(), Matrix.CreateScale(Scale)); vertices[j].TextureCoordinate0 = modelMesh.Vertices[j].TextureCoordinate0.ToVector2(); vertices[j].Tangent = modelMesh.Vertices[j].Tangent.ToVector3(); vertices[j].Binormal = modelMesh.Vertices[j].Binormal.ToVector3(); } OpaqueDataDictionary settings = new OpaqueDataDictionary(); settings["GenerateMipmaps"] = true; IntermediateMaterial im = new IntermediateMaterial(); im.Name = modelMesh.Material.Name; im.DiffuseColor = modelMesh.Material.DiffuseColor.ToVector3(); im.SpecularColor = modelMesh.Material.SpecularColor.ToVector3(); im.SpecularExp = modelMesh.Material.CosinePower.AsSingle(); im.Transparency = modelMesh.Material.Transparency.AsSingle(); im.UseAlpha = modelMesh.Material.UseAlpha.AsBoolean(); im.DrawBackfaces = modelMesh.Material.DrawBackfaces.AsBoolean(); im.Reflectivity = modelMesh.Material.Reflectivity.AsSingle(); //DebugNow(); im.DiffuseMapName = modelMesh.Material.DiffuseMapFilename.AsString(); if (!String.IsNullOrEmpty(im.DiffuseMapName)) { //im.DiffuseMapReference = context.BuildAsset<TextureContent, TextureContent>( // new ExternalReference<TextureContent>( // Path.Combine(Path.GetDirectoryName(input.Path), im.DiffuseMapName)), "TextureProcessor", settings, null, null); } im.NormalMapName = modelMesh.Material.NormalMapFilename.AsString(); if (!String.IsNullOrEmpty(im.NormalMapName)) { //im.BumpMapReference = context.BuildAsset<TextureContent, TextureContent>( // new ExternalReference<TextureContent>( // Path.Combine(Path.GetDirectoryName(input.Path), im.BumpMapName)), "TextureProcessor", settings, null, null); } im.SpecularMapName = modelMesh.Material.SpecularMapFilename.AsString(); if (!String.IsNullOrEmpty(im.SpecularMapName)) { //im.SpecularMapReference = context.BuildAsset<TextureContent, TextureContent>( // new ExternalReference<TextureContent>( // Path.Combine(Path.GetDirectoryName(input.Path), im.SpecularMapName)), "TextureProcessor", settings, null, null); } imm.Indices = modelMesh.Indices.ToInt32Array(); for (int k = 0; k <= imm.Indices.Length - 3; k += 3) { var temp = imm.Indices[k]; imm.Indices[k] = imm.Indices[k + 2]; imm.Indices[k + 2] = temp; } imm.Vertices = vertices; imm.OriginalVertices = origVertices; imm.BoundingSphere = BoundingSphere.CreateFromPoints(vertices.Select(v => v.Position)); imm.BoundingBox = BoundingBox.CreateFromPoints(vertices.Select(v => v.Position)); imm.Material = im; imms.Add(imm); } // Animation stuff List <Matrix> bindPose = new List <Matrix>(); List <Matrix> inverseBindPose = new List <Matrix>(); List <int> skeletonHierarchy = new List <int>(); IDictionary <string, int> boneMap = new Dictionary <string, int>(); IList <String> boneNames = new List <String>(input.BindPose.Count); for (int i = 0; i < input.BindPose.Count; boneNames.Add(String.Empty), ++i) { ; } //DebugNow(); foreach (var joint in input.BindPose) { Matrix transform = Matrix.CreateFromQuaternion(joint.Rotation.ToQuaternion()) * joint.Position.ToTranslationMatrix(); transform.Translation *= Scale; Matrix absoluteTransform = Matrix.CreateFromQuaternion(joint.AbsoluteRotation.ToQuaternion()) * joint.AbsolutePosition.ToTranslationMatrix(); absoluteTransform.Translation *= Scale; bindPose.Add(transform); inverseBindPose.Add(Matrix.Invert(absoluteTransform)); skeletonHierarchy.Add(joint.ParentIndex); boneNames[joint.Index] = joint.Name; boneMap.Add(joint.Name, joint.Index); } var animationClips = ProcessAnimations(input.AnimationKeyframes, input.BindPose, boneNames); var skinningData = new SkinningData(bindPose, inverseBindPose, skeletonHierarchy, boneMap, boneNames, modelName); var animations = PrepareAnimations(animationClips, skinningData, context); model.ModelMeshes = imms.ToArray(); model.AnimationMap = animations; model.SkinningData = skinningData; model.BoundingSphere = BoundingSphere.CreateFromPoints(imms.SelectMany(m => m.Vertices.Select(v => v.Position))); model.BoundingBox = BoundingBox.CreateFromPoints(imms.SelectMany(m => m.Vertices.Select(v => v.Position))); return(model); }