public void BeginPrimitive() { CurrentPrimitive = new ModelPrimitive(); CurrentPrimitive.Indices= new List<ushort>(); Primitives.Add(CurrentPrimitive); }
private static ModelMesh ReadMesh(BinaryReader r) { var data = new ModelMesh(); data.NumVerts = r.ReadInt32(); data.NumPrims = r.ReadInt32(); data.NumRefBones= r.ReadInt32(); data.RefBones = ReadList(r, data.NumRefBones, ReadRefBone); foreach(var i in data.RefBones) i.Matrix = ReadSingleArray(r, 16); data.Vertices = ReadList(r, data.NumVerts, ReadVertex); data.NumTangents= r.ReadInt32(); System.Diagnostics.Debug.Assert(data.NumTangents == 0); data.Tangents = ReadList(r, data.NumTangents, ReadVector4); data.Skins = ReadList(r, data.NumVerts, ReadSkin); //System.Diagnostics.Debug.Assert(data.Unknown2 == 0); data.Primitives = new List<ModelPrimitive>(); for(int i= 0; i < data.NumPrims; ++i) { var prim = new ModelPrimitive(); prim.NumIndices = r.ReadInt32(); prim.Indices = ReadList(r, prim.NumIndices, r.ReadUInt16); data.Primitives.Add(prim); } return data; }
public override void Import(string filename, ModelFile model) { //MorphRange = MorphMax - MorphMin; var importer = new DaeIMImpoter(); Root = importer.Import(filename); var geoms = Root.Instances.OfType<Geometry> ().ToArray(); Vertices = new Dictionary<ModelVertex, int>(); Indices = new List<int>(); var geom = geoms.First(); var mesh = geom.Get<Mesh>("Data"); var posch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Position); var nrmch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Normal); var texch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.TexCoord); var pos = posch.GetDataAsList<SlimDX.Vector3>(); var nrm = nrmch.GetDataAsList<SlimDX.Vector3>(); var tex = texch.GetDataAsList<SlimDX.Vector2>(); var posface = posch.GetIndicesAsList(mesh); var nrmface = nrmch.GetIndicesAsList(mesh); var texface = texch.GetIndicesAsList(mesh); var numidx = posface.Count; for(int i= 0; i < numidx; ++i) { var p = pos[posface[i]]; var n = nrm[nrmface[i]]; var t = tex[texface[i]]; var v = new ModelVertex() { P = new Vector3(p.X, p.Y, p.Z), N = new Vector3(n.X, n.Y, n.Z), T = new Vector2(t.X, t.Y), }; int index; if(!Vertices.TryGetValue(v, out index)) Vertices.Add(v, index= Vertices.Count); Indices.Add(index); } var prims = new List<ModelPrimitive>(); var start = 0; foreach(var i in mesh.Primitives) { var prim = new ModelPrimitive(); prim.Indices = Indices.Skip(start).Take(i.Count).Select(j => (ushort)j).ToList(); prim.NumIndices = Indices.Count; start +=Indices.Count; prims.Add(prim); } model.Mesh.Skins = Vertices.Keys .Select(i => model.Mesh.Skins[FindClosest(model.Mesh.Vertices, i.P)]) .ToList(); model.Mesh.Vertices = Vertices.Keys.ToList(); model.Mesh.NumVerts = model.Mesh.Vertices.Count; model.Mesh.Primitives = prims; model.Mesh.NumPrims = prims.Count; // モーフィングをボディから反映 var morphs = model.Params.OfType<ParamMorph>().ToList(); var body001 = DataManager.Instance.Body001; foreach(var i in morphs) { var index = (ushort)0; var bodymorph = body001.Params.FirstOrDefault(j => j.Name == i.Name) as ParamMorph; var dic = bodymorph.Vertices.ToDictionary(j => j.Index); var dic2 = new Dictionary<int, MorphVertex>(); var rr = Settings.MorphMax - Settings.MorphMin; MorphVertex mv; foreach(var j in model.Mesh.Vertices) { ++index; var near = FindClosest(body001.Mesh.Vertices, j.P); if(!dic.TryGetValue((ushort)near, out mv)) continue; var v = body001.Mesh.Vertices[near]; var x = v.P.X - j.P.X; var y = v.P.Y - j.P.Y; var z = v.P.Z - j.P.Z; var d = (float)Math.Sqrt(x*x + y*y + z*z); if(d >= Settings.MorphMax) continue; var r = d <= Settings.MorphMin ? 1.0f : 1.0f - (d-Settings.MorphMin) / rr; //r = r * MorphScale; var mv2 = new MorphVertex(index-1, mv.X*r, mv.Y*r, mv.Z*r, mv.NX*r, mv.NY*r, mv.NZ*r); dic2.Add((ushort)(index-1), mv2); } i.Vertices = dic2.OrderBy(j => j.Key).Select(j => j.Value).ToList(); i.NumVertices = i.Vertices.Count; } ModelFile.ToFile(model.FileName, model); System.Diagnostics.Debug.Print("終了"); }
public void ImportOld(string filename, ModelFile model) { var importer = new DaeIMImpoter(); Root = importer.Import(filename); var skins = Root.Instances.OfType<SkinDeclaraion> ().ToArray(); var morphs = Root.Instances.OfType<MorphingDeclaraion>().ToArray(); var geoms = Root.Instances.OfType<Geometry> ().ToArray(); Vertices = new Dictionary<ModelVertex, int>(); Indices = new List<int>(); //Skins = new Dictionary<int, ModelSkin>(); if(morphs.Length > 0) { var geom = morphs.First().Source as Geometry; var mesh = geom.Get<Mesh>("Data"); var posch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Position); var nrmch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Normal); var texch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.TexCoord); var pos = posch.GetDataAsList<SlimDX.Vector3>(); var nrm = nrmch.GetDataAsList<SlimDX.Vector3>(); var tex = texch.GetDataAsList<SlimDX.Vector2>(); var posface = posch.GetIndicesAsList(mesh); var nrmface = nrmch.GetIndicesAsList(mesh); var texface = texch.GetIndicesAsList(mesh); var numidx = posface.Count; for(int i= 0; i < numidx; ++i) { var p = pos[posface[i]]; var n = nrm[nrmface[i]]; var t = tex[texface[i]]; var v = new ModelVertex() { P = new Vector3(p.X, p.Y, p.Z), N = new Vector3(n.X, n.Y, n.Z), T = new Vector2(t.X, t.Y), }; int index; if(!Vertices.TryGetValue(v, out index)) Vertices.Add(v, index= Vertices.Count); Indices.Add(index); } var prims = new List<ModelPrimitive>(); var start = 0; foreach(var i in mesh.Primitives) { var prim = new ModelPrimitive(); prim.Indices = Indices.Skip(start).Take(i.Count).Select(j => (ushort)j).ToList(); prim.NumIndices = Indices.Count; start +=Indices.Count; prims.Add(prim); } model.Mesh.Skins = Vertices.Keys .Select(i => model.Mesh.Skins[FindClosest(model.Mesh.Vertices, i.P)]) .ToList(); model.Mesh.Vertices = Vertices.Keys.ToList(); model.Mesh.NumVerts = model.Mesh.Vertices.Count; model.Mesh.Primitives = prims; model.Mesh.NumPrims = prims.Count; // モーフィング model.Params = model.Params.Where(i => !(i is ParamMorph)).ToList(); foreach(var i in morphs.First().Channels) { var mmesh = i.Geometry.Get<Mesh>("Data"); var mposch = mmesh.Channels.FirstOrDefault(j => j.Semantic == GeometrySemantic.Position); var mpos = mposch.GetDataAsList<SlimDX.Vector3>(); var mposidx = mposch.GetIndicesAsList(mmesh); var dic = new Dictionary<int, MorphVertex>(); var mnrm = new SlimDX.Vector3[mpos.Count]; // 法線計算 for(int j= 0; j < mposidx.Count; j+=3) { var a = mpos[mposidx[j+0]]; var b = mpos[mposidx[j+1]]; var c = mpos[mposidx[j+2]]; var ab = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(b, a)); var ac = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(c, a)); var n = SlimDX.Vector3.Normalize(SlimDX.Vector3.Cross(ab, ac)); mnrm[mposidx[j+0]] = SlimDX.Vector3.Add(mnrm[mposidx[j+0]], n); mnrm[mposidx[j+1]] = SlimDX.Vector3.Add(mnrm[mposidx[j+1]], n); mnrm[mposidx[j+2]] = SlimDX.Vector3.Add(mnrm[mposidx[j+2]], n); } for(int j= 0; j < mnrm.Length; ++j) mnrm[j] = SlimDX.Vector3.Normalize(mnrm[j]); for(int j= 0; j < mposidx.Count; ++j) { var ii = (ushort)Indices[j]; var v = model.Mesh.Vertices[ii]; var p = mpos[mposidx[j]]; var n = mnrm[mposidx[j]]; p.X -=v.P.X; p.Y -=v.P.Y; p.Z -=v.P.Z; n.X -=v.N.X; n.Y -=v.N.Y; n.Z -=v.N.Z; dic[ii] = new MorphVertex(ii, p.X, p.Y, p.Z, n.X, n.Y, n.Z); } var morph = new ParamMorph() { Name = i.Geometry.Name, Vertices = dic.OrderBy(j => j.Key).Select(j => j.Value).ToList(), NumVertices = dic.Count, }; model.Params.Insert(0, morph); } } else { throw new Exception(); } ModelFile.ToFile(model.FileName, model); System.Diagnostics.Debug.Print("終了"); }
internal static SubTankMesh FromModel(ModelVisual modelVisual, ModelPrimitive modelPrimitive, IPackageIndexer packageIndexer, Device device, ModelTextureManager textureManager) { if (modelVisual == null) { return(null); } if (modelPrimitive == null) { return(null); } var mesh = new SubTankMesh(); _textureManager = textureManager; var verticesMap = new Dictionary <string, VertexState>(); foreach (var kv in modelPrimitive.Vertices) { var name = kv.Key; var vlist = kv.Value; verticesMap[name] = TankMesh.ConvertToVertexBuffer(vlist, device); } var indicesMap = new Dictionary <string, IndexBuffer>(); foreach (var kv in modelPrimitive.Indices) { var name = kv.Key; var nlist = kv.Value; indicesMap[name] = TankMesh.ConvertToIndexBuffer(nlist, device); } foreach (var renderSet in modelVisual.RenderSets) { //renderSet.Geometry.PrimitiveName var vState = verticesMap[renderSet.Geometry.VerticesName]; var indices = indicesMap[renderSet.Geometry.IndicesName]; var rawVertices = modelPrimitive.Vertices[renderSet.Geometry.VerticesName].Vertices; var rawIndices = modelPrimitive.Indices[renderSet.Geometry.IndicesName]; foreach (var groupKv in renderSet.Geometry.ModelPrimitiveGroups) { var group = groupKv.Value; RenderGroup renderGroup = null; if (group.Sectioned) { renderGroup = new RenderGroup { MinVertexIndex = (int)group.StartVertex, VerticesCount = (int)group.VerticesCount, StartIndex = (int)group.StartIndex, PrimitiveCount = (int)group.PrimitiveCount, }; } else { renderGroup = new RenderGroup { MinVertexIndex = 0, VerticesCount = vState.Count, StartIndex = 0, PrimitiveCount = ((int)indices.Tag) / 3, }; } renderGroup.VertexState = vState; renderGroup.Indices = indices; renderGroup.RawVertices = rawVertices; renderGroup.RawIndices = rawIndices; if (group.Material.ShowArmor) { renderGroup.RenderArmor = true; renderGroup.Textures = null; renderGroup.Armor = group.Material.Armor; } else { renderGroup.RenderArmor = false; var textures = new Dictionary <string, ModelTexture>(); foreach (var property in group.Material.Propertys) { var texturePath = property.Texture; if (string.IsNullOrWhiteSpace(texturePath)) { if (property.Name == "alphaTestEnable" && group.Material.Fx != "shaders/std_effects/PBS_tank.fx") { renderGroup.AlphaTestEnable = property.BoolValue; } else { switch (property.Name) { case "alphaReference": renderGroup.AlphaReference = property.IntValue; break; case "g_useNormalPackDXT1": renderGroup.UseNormalPackDxt1 = property.BoolValue; break; case "g_detailPower": renderGroup.DetailPower = property.FloatValue; break; case "g_metallicDetailUVTiling": renderGroup.DetailUvTiling = property.Vector4Value; break; case "g_defaultPBSConversionParam": break; case "g_albedoConversions": break; case "g_glossConversions": break; case "g_metallicConversions": break; case "g_defaultPBSConversionParams": break; case "g_albedoCorrection": break; case "g_useDetailMetallic": break; case "g_maskBias": break; case "doubleSided": break; case "alphaTestEnable": break; case "crash_coefficient": break; default: break; } } } else { try { var texture = textureManager.LoadTexture(packageIndexer, texturePath, device); textures[property.Name] = texture; if (property.Name == "normalMap" && !renderGroup.UseNormalBc1) { if (texture.ImageInformation.Format == Format.Dxt1) { renderGroup.UseNormalBc1 = true; } } } catch (Exception) { Log.InfoFormat("can't load texture {0} for {1}", texturePath, property.Name); } } } renderGroup.Textures = textures; } mesh._renderGroups.Add(renderGroup); } } return(mesh); }
public void Load(ModelType modelType, IFileLocator fileLocator, Device renderDevice, GraphicsSettings graphicsSettings) { if (_loadCancellationTokenSource != null) { _loadCancellationTokenSource.Cancel(); } _loadCancellationTokenSource = new CancellationTokenSource(); var modelPath = this.ModelObject.GetModelPath(modelType); this.LoadingTask = Task.Factory.StartNew(() => { try { using (Diagnostics.PotentialExceptionRegion) { using (var visualStream = OpenVisualFile(modelPath, fileLocator)) { this.Visual = ModelVisual.ReadFrom(visualStream); foreach (var rendetSet in Visual.RenderSets) { foreach (var group in rendetSet.Geometry.ModelPrimitiveGroups) { var material = group.Value.Material; material.ShowArmor = modelType == ModelType.Collision; material.Armor = this.ArmoredObject.GetArmorGroup(material.Identifier); } } } } } catch (Exception e) { this.LogInfo("exception occurred when loading {0} visual: {1}", modelType, e.Message); } }, _loadCancellationTokenSource.Token) .ContinueWith(_ => { try { using (Diagnostics.PotentialExceptionRegion) { using (var primitivesStream = OpenPrimitiveFile(modelPath, fileLocator)) { this.Primitives = ModelPrimitive.ReadFrom(primitivesStream, Visual, modelType == ModelType.Collision); } } } catch (Exception e) { this.LogInfo("exception occurred when loading {0} primitives: {1}", modelType, e.Message); } }, _loadCancellationTokenSource.Token) .ContinueWith(_ => { var oldMesh = this.Mesh; this.Mesh = new ModuleMesh(this, fileLocator, renderDevice, graphicsSettings); Disposer.RemoveAndDispose(ref oldMesh); }, _loadCancellationTokenSource.Token); }
public Model(ModelViewModel modelViewerViewModel, ITankObject tankObject, ModuleViewModel moduleViewModel) { ModuleViewModel = moduleViewModel; _modelViewerViewModel = modelViewerViewModel; _tankObject = tankObject; DispatchUniqueProperty(); var model = this.ModelObject.Model.Undamaged; LoadingTask = Task.Factory.StartNew(() => { try { using (Diagnostics.PotentialExceptionRegion) { using (var visualStream = this.OpenVisualFile(model)) { this.Visual = ModelVisual.ReadFrom(visualStream); } } } catch (Exception e) { Log.Info("exception occurred when load visual", e); } }).ContinueWith((_) => { try { using (Diagnostics.PotentialExceptionRegion) { using (var modelStream = this.OpenPrimitiveFile(model)) { this.Primitive = ModelPrimitive.ReadFrom(modelStream, this.Visual, false); } } } catch (Exception e) { Log.Info("exception occurred when load primitive", e); } }); var collisionModel = this.ModelObject.Model.Collision; LoadingTask = LoadingTask.ContinueWith((_) => { try { using (Diagnostics.PotentialExceptionRegion) { using (var visualStream = this.OpenVisualFile(collisionModel)) { this.CollisionVisual = ModelVisual.ReadFrom(visualStream); foreach (var rendetSet in CollisionVisual.RenderSets) { foreach (var groupKv in rendetSet.Geometry.ModelPrimitiveGroups) { var material = groupKv.Value.Material; material.ShowArmor = true; if (ArmorObject.Armor.TryGetArmorValue(material.Identifier, out ArmorGroup armor)) { material.Armor = armor; } else { material.Armor = new ArmorGroup(); } } } } } } catch (Exception e) { Log.Info("exception occurred when load collision visual", e); } }).ContinueWith((_) => { try { using (Diagnostics.PotentialExceptionRegion) { using (var modelStream = OpenPrimitiveFile(collisionModel)) { this.CollisionPrimitive = ModelPrimitive.ReadFrom(modelStream, CollisionVisual, true); } } } catch (Exception e) { Log.Info("exception occurred when load collision primitive", e); } }); }