public MeshContainer CreateMeshContainer(string name, MeshData meshData, ExtendedMaterial[] materials, EffectInstance[] effectInstances, int[] adjacency, SkinInfo skinInfo) { var device = meshData.Mesh.Device; GMeshContainer meshContainer = new GMeshContainer(); meshContainer.Name = name; SlimDX.Direct3D9.Mesh mesh = meshData.Mesh; if (!mesh.VertexFormat.HasFlag(VertexFormat.Normal)) { meshContainer.MeshData = new MeshData(mesh.Clone(device, mesh.CreationOptions, mesh.VertexFormat | VertexFormat.Normal)); meshContainer.MeshData.Mesh.ComputeNormals(); } else { meshContainer.MeshData = new MeshData(mesh); } meshContainer.SetMaterials(materials); meshContainer.SetAdjacency(adjacency); meshContainer.SkinInfo = skinInfo; meshContainer.BoneOffsetsMatrix = new Matrix[skinInfo.BoneCount]; for (int i = 0; i < skinInfo.BoneCount; i++) { meshContainer.BoneOffsetsMatrix[i] = skinInfo.GetBoneOffsetMatrix(i); } GenerateSkinnedMesh(device, meshContainer); return(meshContainer); }
//SlimDX.Direct2D.RenderTarget renderTarget; //private void DrawBrush() //{ // // Create bitmap render target from DXGI surface // renderTarget = SlimDX.Direct2D.RenderTarget.FromDXGI(factory, backBuffer, new RenderTargetProperties() // { // HorizontalDpi = 1024, // VerticalDpi = 768, // MinimumFeatureLevel = SlimDX.Direct2D.FeatureLevel.Default, // PixelFormat = new SlimDX.Direct2D.PixelFormat(SlimDX.DXGI.Format.Unknown, SlimDX.Direct2D.AlphaMode.Ignore), // Type = SlimDX.Direct2D.RenderTargetType.Default, // Usage = SlimDX.Direct2D.RenderTargetUsage.None // }); // using (var brush = new SlimDX.Direct2D.SolidColorBrush(renderTarget, new Color4(Color.LightSlateGray))) // { // for (int x = 0; x < renderTarget.Size.Width; x += 10) // renderTarget.DrawLine(brush, x, 0, x, renderTarget.Size.Height, 0.5f); // for (int y = 0; y < renderTarget.Size.Height; y += 10) // renderTarget.DrawLine(brush, 0, y, renderTarget.Size.Width, y, 0.5f); // renderTarget.FillRectangle(brush, new RectangleF(renderTarget.Size.Width / 2 - 50, renderTarget.Size.Height / 2 - 50, 100, 100)); // } // renderTarget.DrawRectangle(new SlimDX.Direct2D.SolidColorBrush(renderTarget, new Color4(Color.CornflowerBlue)), // new RectangleF(renderTarget.Size.Width / 2 - 100, renderTarget.Size.Height / 2 - 100, 200, 200)); //} // DrawMesh //private void DrawMesh(SlimDX.Direct3D9.Mesh mesh, SlimDX.Vector3 loc, bool wireframe = false, bool isFilled = false) /// <summary> /// /////////////////////////////// /// /////////////////////////////// /// /////////////////////////////// /// </summary> // DrawCubeTest private void DrawCubeTest(SlimDX.Vector3 loc, float width, float height, float depth, bool isFilled = true, bool wireframe = false) { if (_mesh == null) { _mesh = SlimDX.Direct3D9.Mesh.CreateBox(D3D.Device, width, height, depth); } _SB.Capture(); //D3D.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Black, 1.0f, 0); var worldMatrix = SlimDX.Matrix.Translation(loc); D3D.Device.SetTransform(TransformState.World, worldMatrix); _mesh.DrawSubset(0); D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Solid); _SB.Apply(); // cleanup if (Vertices != null) { Vertices.Dispose(); } }
public static void Convert(string source, string dest) { FileStream fs = File.Open(source, FileMode.Open, FileAccess.Read); DX.Mesh mesh = DX.Mesh.FromStream(device, fs, DX.MeshFlags.Managed); DX.ExtendedMaterial[] mats = mesh.GetMaterials(); Material[][] outMats = new Material[mats.Length][]; for (int i = 0; i < mats.Length; i++) { outMats[i] = new Material[1]; outMats[i][0] = new Material(null); DX.Material mat = mats[i].MaterialD3D; SlimDX.Color4 clr = mat.Ambient; outMats[i][0].Ambient = new Color4F(clr.Alpha, clr.Red, clr.Green, clr.Blue); clr = mat.Diffuse; outMats[i][0].Diffuse = new Color4F(clr.Alpha, clr.Red, clr.Green, clr.Blue); clr = mat.Specular; outMats[i][0].Specular = new Color4F(clr.Alpha, clr.Red, clr.Green, clr.Blue); outMats[i][0].SetTextureFile(0, mats[i].TextureFileName); } string name = Path.GetFileNameWithoutExtension(source); //EditableMesh outMesh = new EditableMesh(name, mesh, outMats); MeshData data = new MeshData((RenderSystem)null); data.Name = name; data.Materials = outMats; BuildFromMesh(mesh, data, outMats); EditableModel outMdl = new EditableModel(); //mesh.Dispose(); outMdl.Entities = new MeshData[] { data }; //TransformAnimation transAnim = new TransformAnimation(1); //transAnim.Nodes[0].Transforms = new Matrix[1] { Matrix.Identity }; //outMdl.SetTransformAnimInst(new TransformAnimationInstance(transAnim)); EditableModel.ToFile(outMdl, dest); }
// DrawCube //private void DrawCube(SlimDX.Vector3 loc, float width, float height, float depth) //{ // //var mesh = Mesh.CreateBox(D3D.Device, width, height, depth); // if (_mesh == null) // _mesh = Mesh.CreateBox(D3D.Device, width, height, depth); // DrawMesh(_mesh, loc + new SlimDX.Vector3(0, 0, 1.3f), true); //} // DrawCubeTest private void DrawCubeTest(SlimDX.Vector3 loc, float width, float height, float depth, bool isFilled = true, bool wireframe = false) { //var mesh = Mesh.CreateBox(D3D.Device, width, height, depth); if (_mesh == null) { _mesh = Mesh.CreateBox(D3D.Device, width, height, depth); } //light = new Light(); //light.Type = LightType.Point; //light.Range = 75; //light.Position = new SlimDX.Vector3(10, 25, 0); //light.Falloff = 1.0f; //light.Diffuse = System.Drawing.Color.LemonChiffon; //light.Ambient = ambient; //activeMaterial = new Material(); //activeMaterial.Diffuse = System.Drawing.Color.Orange; //activeMaterial.Ambient = ambient; //passiveMaterial = new Material(); //passiveMaterial.Diffuse = System.Drawing.Color.Red; //passiveMaterial.Ambient = ambient; //groundMaterial = new Material(); //groundMaterial.Diffuse = System.Drawing.Color.Green; //groundMaterial.Ambient = ambient; //_mesh.Device. //_mesh.Device.ColorFill() //DrawMesh(_mesh, loc + new SlimDX.Vector3(0, 0, 0.3f)); //DrawMesh(mesh, loc); //_mesh. DrawMesh(_mesh, loc + new SlimDX.Vector3(0, 0, (depth / 2)), wireframe, isFilled); // (depth / 2) prevent drawing below ground if using player coords to draw //DrawMesh(_mesh, loc + new SlimDX.Vector3(0, 0, (depth / 2)), wireframe, isFilled); // (depth / 2) prevent drawing below ground if using player coords to draw //SlimDX.Color4 w_color4 = new SlimDX.Color4(); //w_color4 // GetTexture(D3D.Device, 50, 50, System.Drawing.Color.Red; }
public void Draw3DText(string text, Vector3 textPos, float emSize = 12f, FontStyle fontStyle = FontStyle.Regular) { if (string.IsNullOrEmpty(text)) { throw new ArgumentException(nameof(text)); } if (text == Core.Me.Name) { text = "ME"; } var cam = Camera; var up = new Vector3(0, 1, 0); var fwd = new Vector3(0, 0, 1); var mtx = Conversions.BillboardLh(ref textPos, ref cam, ref up, ref fwd); //mtx.Invert(); Device.SetTransform(TransformState.World, mtx); var meshKey = $"mesh : {text}"; Lazy <Mesh> meshLookup = new Lazy <Mesh>(() => Mesh.CreateText(Device, new System.Drawing.Font("Verdana", emSize, fontStyle), text, 0.001f, 0.01f)); var rec = MemoryCache.Default.AddOrGetExisting(meshKey, meshLookup, CachePolicy); Mesh m; if (rec == null) { m = meshLookup.Value; } else { m = ((Lazy <Mesh>)rec).Value; } m.DrawSubset(0); Device.SetTransform(TransformState.World, Matrix.Identity); }
// DrawCubeTest private static void DrawCubeTest(SlimDX.Vector3 loc, float width, float height, float depth, bool isFilled = true, bool wireframe = false) { if (_mesh == null) { _mesh = SlimDX.Direct3D9.Mesh.CreateBox(D3D.Device, width, height, depth); } _SB.Capture(); var worldMatrix = SlimDX.Matrix.Translation(loc); D3D.Device.SetTransform(TransformState.World, worldMatrix); _mesh.DrawSubset(0); D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Solid); _SB.Apply(); }
// DrawMesh private void DrawMesh(SlimDX.Direct3D9.Mesh mesh, SlimDX.Vector3 loc, bool wireframe = false, bool isFilled = false) { light = new Light(); light.Type = LightType.Point; light.Range = 75; light.Position = new SlimDX.Vector3(10, 25, 0); light.Falloff = 1.0f; light.Diffuse = System.Drawing.Color.LemonChiffon; light.Ambient = ambient; activeMaterial = new Material(); activeMaterial.Diffuse = System.Drawing.Color.Orange; activeMaterial.Ambient = ambient; passiveMaterial = new Material(); passiveMaterial.Diffuse = System.Drawing.Color.Red; passiveMaterial.Ambient = ambient; groundMaterial = new Material(); groundMaterial.Diffuse = System.Drawing.Color.Green; groundMaterial.Ambient = ambient; if (isFilled) { if (wireframe) { D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Solid); } } else { if (wireframe) { D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Wireframe); } } var worldMatrix = SlimDX.Matrix.Translation(loc); //D3D.Device.SetLight(0, light); //D3D.Device.EnableLight(0, true); //D3D.Device.SetRenderState(RenderState.Ambient, ambient.ToArgb()); //D3D.Device.Material = groundMaterial; D3D.Device.SetTransform(TransformState.World, worldMatrix); mesh.DrawSubset(0); if (isFilled) { if (wireframe) { D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Wireframe); } } else { //if (wireframe) //D3D.Device.SetRenderState(RenderState.FillMode, SlimDX.Direct3D9.FillMode.Solid); } }
public override void Init() { Content.ContentPath = ""; Content.ContentCachePath = "Cache/"; Meshes.Load(Device); billboard = Meshes.PositionTexcoord(Device, Meshes.IndexedPlane(-8.1640625f, -62f / 20f, 38, 62 / 2f)); plane = Meshes.PositionTexcoord(Device, Meshes.IndexedGrid(new Vector3(-0.5f, -0.5f, 0), new Vector2(1, 1), 128, 128, Vector2.Zero, new Vector2(1, 1))); tree = SlimDX.Direct3D9.Mesh.FromFile(Device, "spruce.x", MeshFlags.Managed); unit = SlimDX.Direct3D9.Mesh.FromFile(Device, "unitcylinder.x", MeshFlags.Managed); Reloadable.Load((efn) => { Effect e = EffectUtil.LoadWithDebugger(Device, efn); if(e == null) return; if (ef != null) ef.Dispose(); ef = e; }, "geomorph.fx"); text = Texture.FromFile(Device, "ground.jpg", Usage.None, Pool.Managed); text.GenerateMipSublevels(); treeMap = Texture.FromFile(Device, "spruce.tga", Usage.None, Pool.Managed); treeMap.GenerateMipSublevels(); treeBillboard = Texture.FromFile(Device, "spruceBillboard.tga", Usage.None, Pool.Managed); treeBillboard.GenerateMipSublevels(); String hm = "heightmap-landscape.tga"; HeightmapProcessor heightmapProcessor = new HeightmapProcessor(); Reloadable.Load((h) => { if (heightMap != null) heightMap.Dispose(); heightMap = heightmapProcessor.Load(Device, h); }, hm); textureSize = heightMap.GetLevelDescription(0).Width; terrain = new GeoclipmappedTerrain(Device, resolution); DataRectangle r = heightMap.LockRectangle(0, LockFlags.ReadOnly); data = TextureUtil.ReadTexture<ClientCommon.TextureColor.R32G32B32A32F>(r, textureSize); heightMap.UnlockRectangle(0); DataRectangle r2 = heightMap.LockRectangle(5, LockFlags.ReadOnly); dataLod2 = TextureUtil.ReadTexture<ClientCommon.TextureColor.R32G32B32A32F>(r2, textureSize/(int)Math.Pow(2, 5)); heightMap.UnlockRectangle(5); float prev = 20; cam = new WalkaroundCamera(this, (float x, float y) => { float z = HeightAt(data, x, y); float re = z * 0.05f + prev * 0.95f; prev = re; return re + 1.8f; }); cam.ZFar *= 100; cam.Speed = 2; values = new Values(); values.Show(); instanceVD = new VertexDeclaration(Device, instanceVES); instancingVB = new VertexBuffer(Device, ntrees * Vector3.SizeInBytes, Usage.None, VertexFormat.None, Pool.Managed); Random ra = new Random(0); trees = new Vector3[ntrees]; treeRidgeDiff = new float[ntrees]; for (int i = 0; i < ntrees/40; i++) { float x = ((float)ra.NextDouble() - 0.5f) * heightmapScale; float y = ((float)ra.NextDouble() - 0.5f) * heightmapScale * 0.5f; for (int k = 0; k < 40; k++) { float x1 = x + ((float)ra.NextDouble() - 0.5f) * 100; float y1 = y + ((float)ra.NextDouble() - 0.5f) * 100; float z = HeightAt(data, x1, y1); trees[i*40 + k] = new Vector3(x1, y1, z); treeRidgeDiff[i*40 + k] = HeightAt(dataLod2, x1, y1) - z; } } //Fullscreen = false; }
private AnimationFrame CreateFrame(Transform frame, AnimatorEditor editor, HashSet<string> extractFrames, HashSet<string> meshNames, Device device, List<AnimationFrame> meshFrames, Dictionary<string, Tuple<Matrix, Matrix>> extractMatrices) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.GetTransformPath(); animationFrame.TransformationMatrix = Matrix.Scaling(frame.m_LocalScale) * Matrix.RotationQuaternion(frame.m_LocalRotation) * Matrix.Translation(frame.m_LocalPosition); animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = extractMatrices[animationFrame.Name].Item1; if (meshNames.Contains(animationFrame.Name)) { MeshRenderer meshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); if (meshR == null) { meshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } if (meshR != null) { Mesh mesh = Operations.GetMesh(meshR); if (mesh != null) { SkinnedMeshRenderer smr = meshR as SkinnedMeshRenderer; List<PPtr<Transform>> boneList = null; string[] boneNames = null; Matrix[] boneOffsets = null; if (smr != null && smr.m_Bones.Count > 0) { boneList = smr.m_Bones; int numBones = boneList.Count > 0 ? extractFrames.Count : 0; boneNames = new string[numBones]; boneOffsets = new Matrix[numBones]; if (numBones > 0) { string[] extractArray = new string[numBones]; extractFrames.CopyTo(extractArray); HashSet<string> extractCopy = new HashSet<string>(extractArray); int invalidBones = 0; for (int i = 0; i < boneList.Count; i++) { Transform bone = boneList[i].instance; if (bone == null || bone.m_GameObject.instance == null || !extractCopy.Remove(bone.GetTransformPath())) { invalidBones++; } else if (i < numBones) { boneNames[i] = bone.GetTransformPath(); boneOffsets[i] = Operations.Mirror(Matrix.Transpose(mesh.m_BindPose[i])); } } extractCopy.CopyTo(boneNames, boneList.Count - invalidBones); for (int i = boneList.Count; i < extractFrames.Count; i++) { boneOffsets[i] = extractMatrices[boneNames[i]].Item2; } } } AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.m_SubMeshes.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); Operations.vMesh vMesh = new Operations.vMesh(meshR, true, true); for (int i = 0; i < mesh.m_SubMeshes.Count; i++) { Operations.vSubmesh submesh = vMesh.submeshes[i]; List<Operations.vFace> faceList = submesh.faceList; List<Operations.vVertex> vertexList = submesh.vertexList; SlimDX.Direct3D9.Mesh animationMesh = null; PositionBlendWeightsIndexedColored[] normalLines = null; try { animationMesh = new SlimDX.Direct3D9.Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].index; indexStream.Write(indices[0]); indexStream.Write(indices[2]); indexStream.Write(indices[1]); } animationMesh.UnlockIndexBuffer(); } FillVertexBuffer(animationMesh, vertexList, -1); normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { Operations.vVertex vertex = vertexList[j]; byte[] bIdx; float[] bWeights; if (vertex.boneIndices != null) { bIdx = new byte[4] { (byte)vertex.boneIndices[0], (byte)vertex.boneIndices[1], (byte)vertex.boneIndices[2], (byte)vertex.boneIndices[3] }; bWeights = vertex.weights; } else { bIdx = new byte[4]; bWeights = new float[4]; } normalLines[j * 2] = new PositionBlendWeightsIndexedColored(vertex.position, bWeights, bIdx, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.position + (vertex.normal / 64), bWeights, bIdx, Color.Yellow.ToArgb()); min = Vector3.Minimize(min, vertex.position); max = Vector3.Maximize(max, vertex.position); } } catch { Report.ReportLog("No display of submeshes with more than 64k vertices!"); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); if (animationMesh != null) { meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; } meshContainers[i] = meshContainer; if (submesh.matList.Count > 0 && submesh.matList[0].instance != null) { Material mat = submesh.matList[0].instance; int matIdx = editor.Materials.IndexOf(mat); int texIdx; if (!MatTexIndices.TryGetValue(matIdx, out texIdx)) { texIdx = -1; SlimDX.Direct3D9.Material materialD3D = new SlimDX.Direct3D9.Material(); materialD3D.Ambient = GetColour(mat, "_SColor"); materialD3D.Diffuse = GetColour(mat, "_Color"); materialD3D.Emissive = GetColour(mat, "_ReflectColor"); materialD3D.Specular = GetColour(mat, "_SpecColor"); materialD3D.Power = GetFloat(mat, "_Shininess"); Materials[matIdx] = materialD3D; Texture2D matTex = GetTexture(mat, "_MainTex"); if (matTex != null) { texIdx = editor.Textures.IndexOf(matTex); if (Textures[texIdx] == null) { using (MemoryStream mem = new MemoryStream()) { matTex.Export(mem); mem.Position = 0; ImportedTexture image = new ImportedTexture(mem, matTex.m_Name); Textures[texIdx] = Texture.FromMemory(device, image.Data); } } } MatTexIndices.Add(matIdx, texIdx); } meshContainer.MaterialIndex = matIdx; meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } if (boneList != null) { for (int i = 0; i < meshContainers.Length; i++) { meshContainers[i].BoneNames = boneNames; meshContainers[i].BoneOffsets = boneOffsets; meshContainers[i].RealBones = boneList.Count; } } Matrix mirrorCombined = Operations.Mirror(animationFrame.CombinedTransform); min = Vector3.TransformCoordinate(min, mirrorCombined); max = Vector3.TransformCoordinate(max, mirrorCombined); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } } } for (int i = 0; i < frame.Count; i++) { Transform child = frame[i]; if (extractFrames.Contains(child.GetTransformPath())) { AnimationFrame childAnimationFrame = CreateFrame(child, editor, extractFrames, meshNames, device, meshFrames, extractMatrices); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
public static void BuildFromMesh(DX.Mesh mesh, MeshData <Material> data, Material[][] mats) { void *src = mesh.LockVertexBuffer(DX.LockFlags.None).DataPointer.ToPointer(); byte[] buffer = new byte[mesh.VertexCount * mesh.BytesPerVertex]; fixed(byte *dst = &buffer[0]) { Memory.Copy(src, dst, buffer.Length); data.SetData(dst, buffer.Length); } mesh.UnlockVertexBuffer(); data.Materials = mats; data.MaterialAnimation = new MaterialAnimationInstance[mats.Length]; //{ new MaterialAnimationInstance(matAnimData) }; for (int i = 0; i < mats.Length; i++) { MaterialAnimation matAnimData = new MaterialAnimation(mats[i].Length, 0.025f); data.MaterialAnimation[i] = new MaterialAnimationInstance(matAnimData); } data.VertexSize = mesh.BytesPerVertex; data.VertexCount = mesh.VertexCount; DX.VertexElement[] elements = DX.D3DX.DeclaratorFromFVF(mesh.VertexFormat); data.VertexElements = new VertexElement[elements.Length]; for (int i = 0; i < elements.Length - 1; i++) { data.VertexElements[i] = new VertexElement(elements[i].Offset, Convert(elements[i].Type), Convert(elements[i].Usage), elements[i].UsageIndex); //data.VertexElements [i]= new VertexElement (elements[i].Offset, //data.VertexElements[i].Index = elements[i].UsageIndex; //data.VertexElements[i].Offset = elements[i].Offset; //data.VertexElements[i].s } //Array.Copy(elements, data.VertexElements, elements.Length); int faceCount = mesh.FaceCount; data.Faces = new MeshFace[faceCount]; uint *ab = (uint *)mesh.LockAttributeBuffer(DX.LockFlags.ReadOnly).DataPointer.ToPointer(); if ((mesh.CreationOptions & DX.MeshFlags.Use32Bit) == DX.MeshFlags.Use32Bit) { uint *ib = (uint *)mesh.LockIndexBuffer(DX.LockFlags.ReadOnly).DataPointer.ToPointer(); for (int i = 0; i < faceCount; i++) { int idxId = i * 3; data.Faces[i] = new MeshFace((int)ib[idxId], (int)ib[idxId + 1], (int)ib[idxId + 2], (int)ab[i]); } mesh.UnlockIndexBuffer(); } else { ushort *ib = (ushort *)mesh.LockIndexBuffer(DX.LockFlags.ReadOnly).DataPointer.ToPointer(); for (int i = 0; i < faceCount; i++) { int idxId = i * 3; data.Faces[i] = new MeshFace(ib[idxId], ib[idxId + 1], ib[idxId + 2], (int)ab[i]); } mesh.UnlockIndexBuffer(); } mesh.UnlockAttributeBuffer(); }
public Patch(Device device, HeightMap heightMap, int left, int top, int right, int bottom) { int width = right - left; int height = bottom - top; int numFace = (int)(width * height * 2); int numVertex = (int)((width + 1) * (height + 1)); this.mesh = new D3D.Mesh(device.RawDevice, numFace, numVertex, 0, this.terrainFvf); // Create terrain vertices var vertices = this.mesh.LockVertexBuffer(D3D.LockFlags.None); for (int z = top, z0 = 0; z <= bottom; ++z, ++z0) { for (int x = left, x0 = 0; x <= right; ++x, ++x0) { var pos = new Vector3(x, heightMap.GetHeight(x, z), z); var uv = new Vector2(x * 0.2f, z * 0.2f); vertices.Write(new TerrainVertex(pos, uv)); } } this.mesh.UnlockVertexBuffer(); // Calculate terrain indices var indices = this.mesh.LockIndexBuffer(D3D.LockFlags.None); for (int z = top, z0 = 0; z < bottom; ++z, ++z0) { for (int x = left, x0 = 0; x < right; ++x, ++x0) { // Triangle 1 indices.Write((short)(z0 * (width + 1) + x0)); indices.Write((short)((z0 + 1) * (width + 1) + x0)); indices.Write((short)(z0 * (width + 1) + x0 + 1)); // Triangle 2 indices.Write((short)(z0 * (width + 1) + x0 + 1)); indices.Write((short)((z0 + 1) * (width + 1) + x0)); indices.Write((short)((z0 + 1) * (width + 1) + x0 + 1)); } } this.mesh.UnlockIndexBuffer(); // Set attributes var attributes = this.mesh.LockAttributeBuffer(D3D.LockFlags.None); for (int z = top; z < bottom; ++z) { for (int x = left; x < right; ++x) { // Calculate vertices based on height int subset; if (heightMap.GetHeight(x, z) == 0.0f) subset = 0; else if (heightMap.GetHeight(x, z) <= heightMap.MaxHeight * 0.6f) subset = 1; else subset = 2; attributes.Write(subset); attributes.Write(subset); } } this.mesh.UnlockAttributeBuffer(); // Compute normal for the terrain this.mesh.ComputeNormals(); }
public static SlimDX.Direct3D9.Mesh XPositionTexcoordNormal(Device device, IndexedFeed feed) { SlimDX.Direct3D9.Mesh mesh = null; DataStream vertices = null; DataStream indices = null; bool useShortIndices = true; feed((nVertices, nFaces) => { mesh = new SlimDX.Direct3D9.Mesh(device, nFaces, nVertices, MeshFlags.Managed, VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Normal); vertices = mesh.VertexBuffer.Lock(0, nVertices * (Vector3.SizeInBytes + Vector2.SizeInBytes + Vector3.SizeInBytes), LockFlags.None); indices = mesh.IndexBuffer.Lock(0, sizeof(short) * nFaces * 3, LockFlags.None); }, (pos, texcoord) => { vertices.Write(pos); vertices.Write(new Vector3(1, 1, 1)); vertices.Write(texcoord); }, (index) => { if (useShortIndices) indices.Write<short>((short)index); else indices.Write<int>((int)index); }); mesh.VertexBuffer.Unlock(); mesh.IndexBuffer.Unlock(); return mesh; }
public static SlimDX.Direct3D9.Mesh XPositionTexcoord(Device device, IndexedFeed feed) { VertexElement[] ve = new VertexElement[]{ new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), new VertexElement(0, (short)Vector3.SizeInBytes, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0), VertexElement.VertexDeclarationEnd }; SlimDX.Direct3D9.Mesh mesh = null; DataStream vertices = null; DataStream indices = null; bool useShortIndices = true; feed((nVertices, nFaces) => { mesh = new SlimDX.Direct3D9.Mesh(device, nFaces, nVertices, MeshFlags.Managed, VertexFormat.Position | VertexFormat.Texture1); vertices = mesh.VertexBuffer.Lock(0, nVertices*(Vector3.SizeInBytes + Vector2.SizeInBytes), LockFlags.None); indices = mesh.IndexBuffer.Lock(0, sizeof(short)*nFaces*3, LockFlags.None); }, (pos, texcoord) => { vertices.Write(pos); vertices.Write(texcoord); }, (index) => { if (useShortIndices) indices.Write<short>((short)index); else indices.Write<int>((int)index); }); mesh.VertexBuffer.Unlock(); mesh.IndexBuffer.Unlock(); return mesh; }
private SkelletalMesh GetMesh(GMeshContainer meshContainer, Bone root, VertexDescriptor vd) { SlimDX.Direct3D9.Mesh d3dMesh = meshContainer.Mesh; var adjacency = meshContainer.GetAdjacency(); var meshMaterials = meshContainer.GetMaterials(); List <MeshMaterial> materials = new List <MeshMaterial>(); for (int i = 0; i < meshMaterials.Length; i++) { var matd3d = meshMaterials[i].MaterialD3D; string textureFilename = meshMaterials[i].TextureFileName; if (textureFilename != null && !Path.IsPathRooted(textureFilename)) { textureFilename = Path.Combine(Path.GetDirectoryName(xFile), textureFilename); } materials.Add(new MeshMaterial() { Name = root.Name + "_material" + i, Alpha = matd3d.Diffuse.Alpha, Diffuse = matd3d.Diffuse.ToVector3(), Specular = matd3d.Specular.ToVector3(), SpecularPower = Math.Max(1, matd3d.Power), Reflectivity = 0, Refractitity = 0, EmissiveColor = matd3d.Emissive.ToVector3(), DiffuseMap = textureFilename }); } SkelletalMesh mesh = new SkelletalMesh(vd); mesh.Adjacency = adjacency; SkinVertex[] vertexes = new SkinVertex[d3dMesh.VertexCount]; Array indices; if (d3dMesh.IndexBuffer.Description.Format == Format.Index16) { indices = new ushort[d3dMesh.FaceCount * 3]; } else { indices = new uint[d3dMesh.FaceCount * 3]; } VertexDescriptor meshVD = new VertexDescriptor(d3dMesh.GetDeclaration()); int positionOffset = meshVD.GetOffset(DeclarationUsage.Position, 0); int normalOffset = meshVD.GetOffset(DeclarationUsage.Normal, 0); int texCoordOffset = meshVD.GetOffset(DeclarationUsage.TextureCoordinate, 0); int blendIndicesOffset = meshVD.GetOffset(DeclarationUsage.BlendIndices, 0); int blendIndicesSize = meshVD.SizeOfElement(DeclarationUsage.BlendIndices, 0); int blendWeightsOffset = meshVD.GetOffset(DeclarationUsage.BlendWeight, 0); int blendWeightSize = meshVD.SizeOfElement(DeclarationUsage.BlendWeight, 0); byte[] buffer; unsafe { DataStream vertexStream = d3dMesh.LockVertexBuffer(0); buffer = new byte[vertexStream.Length]; vertexStream.Read(buffer, 0, (int)vertexStream.Length); fixed(byte *_pter = buffer) { fixed(SkinVertex *pVertexes = vertexes) { byte *pter = _pter; int j = 0; for (int i = 0; i < d3dMesh.VertexCount; i++) { pVertexes[i].Position = *((Vector3 *)(pter + positionOffset)); if (normalOffset >= 0) { pVertexes[i].Normal = *((Vector3 *)(pter + normalOffset)); } if (texCoordOffset >= 0) { pVertexes[i].TexCoord = *((Vector2 *)(pter + texCoordOffset)); } if (blendIndicesOffset >= 0) { byte *indicesPter = (pter + blendIndicesOffset); uint *pDest = (uint *)&(pVertexes[i].BlendIndices); for (j = 0; j < blendIndicesSize; j++) { *(((byte *)pDest) + j) = *(indicesPter + j); } } if (blendWeightsOffset >= 0) { byte * weightsPter = (pter + blendWeightsOffset); Vector4 *pDest = &(pVertexes[i].BlendWeights); for (j = 0; j < blendWeightSize; j++) { *(((byte *)pDest) + j) = *(weightsPter + j); } } pter += d3dMesh.BytesPerVertex; } } } d3dMesh.UnlockVertexBuffer(); DataStream indexStream = d3dMesh.LockIndexBuffer(0); GCHandle handler = GCHandle.Alloc(indices, GCHandleType.Pinned); IntPtr indexPter = Marshal.UnsafeAddrOfPinnedArrayElement(indices, 0); buffer = new byte[indexStream.Length]; indexStream.Read(buffer, 0, (int)indexStream.Length); Marshal.Copy(buffer, 0, indexPter, buffer.Length); handler.Free(); d3dMesh.UnlockIndexBuffer(); } mesh.CreateVertexBuffer(vertexes); if (d3dMesh.IndexBuffer.Description.Format == Format.Index16) { mesh.CreateIndexBuffer((ushort[])indices); } else { mesh.CreateIndexBuffer((uint[])indices); } List <MeshLayer> layers = new List <MeshLayer>(); if (meshContainer.BoneCombinations == null || meshContainer.BoneCombinations.Length == 0) { MeshLayer component = new MeshLayer(); materials.Add(MeshMaterial.CreateDefaultMaterial(meshContainer.Name + "_default")); component.materialIndex = 0; component.primitiveCount = mesh.FaceCount; component.startIndex = 0; component.startVertex = 0; component.vertexCount = mesh.VertexCount; layers.Add(component); } else { for (int i = 0; i < meshContainer.BoneCombinations.Length; i++) { BoneCombination comb = meshContainer.BoneCombinations[i]; MeshLayer component = new MeshLayer(); component.materialIndex = comb.AttributeId; component.primitiveCount = comb.FaceCount; component.startIndex = comb.FaceStart * 3; component.startVertex = comb.VertexStart; component.vertexCount = comb.VertexCount; layers.Add(component); } } var layerArray = layers.ToArray(); mesh.Materials = materials.ToArray(); mesh.SetLayers(layerArray); var skinInfo = meshContainer.SkinInfo; mesh.MaxVertexInfluences = skinInfo.MaximumVertexInfluences; var bones = new Bone[skinInfo.BoneCount]; var boneOffsetMatrices = new Matrix[bones.Length]; for (int i = 0; i < bones.Length; i++) { bones[i] = root.FindChild(skinInfo.GetBoneName(i)); boneOffsetMatrices[i] = skinInfo.GetBoneOffsetMatrix(i); } mesh.Bones = bones; mesh.BoneBindingMatrices = boneOffsetMatrices; if (meshContainer.BoneCombinations != null && meshContainer.BoneCombinations.Length > 0) { for (int layerIndex = 0; layerIndex < layerArray.Length; layerIndex++) { mesh.SetLayerBones(layerIndex, meshContainer.BoneCombinations[layerIndex].BoneIds); } } mesh.LockVertexBuffer(); int[] vertices; float[] weights; for (int i = 0; i < mesh.bones.Length; i++) { skinInfo.GetBoneInfluence(i, out vertices, out weights); VertexStreamView <Vector3> positions = mesh.GetVertexViewStream <Vector3>(DeclarationUsage.Position, 0, vertices); } mesh.UnlockVertexBuffer(); meshVD.Dispose(); if (normalOffset < 0) { mesh.ComputeNormals(); } if (texCoordOffset < 0) { mesh.ComputeTextureCoords(CoordMappingType.Spherical); } mesh.ComputeTangents(); return(mesh); }
public SceneImportResult LoadStaticMesh(string filename) { var file = new FileInfo(filename); VertexDescriptor vd = VertexDescriptor.Get <ModelVertex>(); List <MeshLayer> layers = new List <MeshLayer>(); int[] adjacency; ExtendedMaterial[] meshMaterials; Mesh mesh = new Mesh(vd); List <MeshMaterial> material = new List <MeshMaterial>(); using (SlimDX.Direct3D9.Mesh d3dMesh = SlimDX.Direct3D9.Mesh.FromFile(Engine.Graphics, filename, MeshFlags.Managed)) { adjacency = d3dMesh.GetAdjacency(); meshMaterials = d3dMesh.GetMaterials(); for (int i = 0; i < meshMaterials.Length; i++) { var matd3d = meshMaterials[i].MaterialD3D; string textureFilename = meshMaterials[i].TextureFileName; if (textureFilename != null && !Path.IsPathRooted(textureFilename)) { textureFilename = Path.Combine(Path.GetDirectoryName(filename), textureFilename); } material.Add(new MeshMaterial() { Name = file.Name + "_material" + i, Alpha = matd3d.Diffuse.Alpha, Diffuse = matd3d.Diffuse.ToVector3(), Specular = matd3d.Specular.ToVector3(), SpecularPower = Math.Max(1, matd3d.Power), Reflectivity = 0, Refractitity = 0, EmissiveColor = matd3d.Emissive.ToVector3(), DiffuseMap = textureFilename != null && File.Exists(textureFilename) ? textureFilename : null }); } ModelVertex[] vertexes = new ModelVertex[d3dMesh.VertexCount]; Array indices; if (d3dMesh.IndexBuffer.Description.Format == Format.Index16) { indices = new ushort[d3dMesh.FaceCount * 3]; } else { indices = new uint[d3dMesh.FaceCount * 3]; } DataStream vertexStream = d3dMesh.LockVertexBuffer(0); VertexDescriptor meshVD = new VertexDescriptor(d3dMesh.GetDeclaration()); int positionOffset = meshVD.GetOffset(DeclarationUsage.Position, 0); int normalOffset = meshVD.GetOffset(DeclarationUsage.Normal, 0); int texCoordOffset = meshVD.GetOffset(DeclarationUsage.TextureCoordinate, 0); byte[] buffer; unsafe { buffer = new byte[vertexStream.Length]; vertexStream.Read(buffer, 0, (int)vertexStream.Length); fixed(byte *_pter = buffer) { byte *pter = _pter; for (int i = 0; i < d3dMesh.VertexCount; i++) { vertexes[i].Position = *((Vector3 *)(pter + positionOffset)); if (normalOffset > 0) { vertexes[i].Normal = *((Vector3 *)(pter + normalOffset)); } if (texCoordOffset > 0) { vertexes[i].TexCoord = *((Vector2 *)(pter + texCoordOffset)); } pter += d3dMesh.BytesPerVertex; } } d3dMesh.UnlockVertexBuffer(); DataStream indexStream = d3dMesh.LockIndexBuffer(0); GCHandle handler = GCHandle.Alloc(indices, GCHandleType.Pinned); byte * indexPter = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(indices, 0); buffer = new byte[indexStream.Length]; indexStream.Read(buffer, 0, (int)indexStream.Length); for (int i = 0; i < indexStream.Length; i++) { indexPter[i] = buffer[i]; } handler.Free(); d3dMesh.UnlockIndexBuffer(); } mesh.CreateVertexBuffer(vertexes); if (d3dMesh.IndexBuffer.Description.Format == Format.Index16) { mesh.CreateIndexBuffer((ushort[])indices); } else { mesh.CreateIndexBuffer((uint[])indices); } var d3dComponents = d3dMesh.GetAttributeTable(); if (d3dComponents == null) { MeshLayer component = new MeshLayer(); layers.Add(component); material.Add(MeshMaterial.CreateDefaultMaterial(file.Name + "_default")); component.materialIndex = 0; component.primitiveCount = mesh.FaceCount; component.startIndex = 0; component.startVertex = 0; component.vertexCount = mesh.VertexCount; } else { for (int i = 0; i < d3dComponents.Length; i++) { AttributeRange ar = d3dComponents[i]; MeshLayer component = new MeshLayer(); layers.Add(component); component.materialIndex = ar.AttribId; component.primitiveCount = ar.FaceCount; component.startIndex = ar.FaceStart * 3; component.startVertex = ar.VertexStart; component.vertexCount = ar.VertexCount; } } mesh.Materials = material.ToArray(); mesh.SetLayers(layers.ToArray()); if (normalOffset < 0) { mesh.ComputeNormals(); } if (texCoordOffset < 0) { mesh.ComputeTextureCoords(CoordMappingType.Spherical); } mesh.ComputeTangents(); meshVD.Dispose(); } StaticMeshSceneNode meshNode = new StaticMeshSceneNode(file.Name, mesh); return(new SceneImportResult { VisualSceneRoot = meshNode, VisualMaterials = material }); }