private SCNGeometry CreateTrailMesh(List <SCNVector3> positions, List <SCNVector4> colors) { SCNGeometry result = null; if (positions.Count >= 4) { var array = new byte[positions.Count]; for (byte i = 0; i < positions.Count; i++) { array[i] = i; } var positionSource = SCNGeometrySource.FromVertices(positions.ToArray()); var colorSource = SCNGeometrySourceExtensions.Create(colors); var element = SCNGeometryElement.FromData(NSData.FromArray(array), SCNGeometryPrimitiveType.TriangleStrip, positions.Count - 2, 2); result = SCNGeometry.Create(new SCNGeometrySource[] { positionSource, colorSource }, new SCNGeometryElement[] { element }); var material = result.FirstMaterial; if (material == null) { throw new Exception("created geometry without material"); } material.DoubleSided = true; material.LightingModelName = SCNLightingModel.Constant; material.BlendMode = SCNBlendMode.Add; material.WritesToDepthBuffer = false; } return(result); }
public SCNGeometry ImportOBJ(string path) { string[] fileContents = File.ReadLines(path).ToArray(); GetLines(fileContents); polygonCount = indexLines.Length; int[] vertexIndexPrefix = SplitIndices(indexLines).Item1; int[] vertexIndices = SplitIndices(indexLines).Item2; int[] normalIndices = SplitIndices(indexLines).Item3; SCNVector3[] vertexPoints = LinesToPoints(vertexLines); SCNVector3[] normalPoints = LinesToPoints(normalLines); SCNVector3[] vertices = OrderPoints(vertexPoints, vertexIndices); SCNVector3[] normals = OrderPoints(normalPoints, normalIndices); vertexIndices = ReorderIndices(vertexIndexPrefix, vertexIndices); NSData vertexIndexData = IndexData(vertexIndices); SCNGeometrySource vertexSource = SCNGeometrySource.FromVertices(vertices); SCNGeometrySource normalSource = SCNGeometrySource.FromNormals(normals); SCNGeometryElement vertexElement = SCNGeometryElement.FromData(vertexIndexData, SCNGeometryPrimitiveType.Polygon, polygonCount, sizeof(int)); return(SCNGeometry.Create(new[] { vertexSource, normalSource }, new[] { vertexElement })); }
public SCNGeometry MakeMeshGeometry(SCNVector3[] vertices, SCNVector3[] normals, List <int> faces) { var geometrySources = new[] { SCNGeometrySource.FromVertices(vertices), SCNGeometrySource.FromNormals(normals) }; var array = faces.SelectMany(v => BitConverter.GetBytes(v)).ToArray(); var indexData = NSData.FromArray(array); var elementSource = SCNGeometryElement.FromData(indexData, SCNGeometryPrimitiveType.Triangles, (nint)(faces.Count / 3), (nint)sizeof(int)); var geometry = SCNGeometry.Create(geometrySources, new[] { elementSource }); geometry.WantsAdaptiveSubdivision = false; return(geometry); }
public static SCNGeometry ToSCNGeometry(this Solid csg) { if (csg.Polygons.Count == 0) { return(SCNGeometry.Create()); } else { var verts = csg. Polygons. SelectMany(x => x.Vertices). Select(ToSCNVector3). ToArray(); var norms = csg. Polygons. SelectMany(x => { var n = x.Plane.Normal.ToSCNVector3(); return(x.Vertices.Select(_ => n)); }). ToArray(); var vertsSource = SCNGeometrySource.FromVertices(verts); var normsSource = SCNGeometrySource.FromNormals(norms); var sources = new[] { vertsSource, normsSource }; var triStream = new System.IO.MemoryStream(); var triWriter = new System.IO.BinaryWriter(triStream); var triCount = 0; var vi = 0; foreach (var p in csg.Polygons) { for (var i = 2; i < p.Vertices.Count; i++) { triWriter.Write(vi); triWriter.Write(vi + i - 1); triWriter.Write(vi + i); } triCount += p.Vertices.Count - 2; vi += p.Vertices.Count; } triWriter.Flush(); var triData = NSData.FromArray(triStream.ToArray()); var elem = SCNGeometryElement.FromData(triData, SCNGeometryPrimitiveType.Triangles, triCount, 4); var elements = new[] { elem }; var g = SCNGeometry.Create(sources, elements); g.FirstMaterial.Diffuse.ContentColor = NSColor.LightGray; return(g); } }
internal static SCNGeometry CreateVisualization(NVector3[] points, UIColor color, float size) { if (points.Length == 0) { return(null); } unsafe { var stride = sizeof(float) * 3; // Pin the data down so that it doesn't move fixed(NVector3 *pPoints = &points[0]) { // Grab a pointer to the data and treat it as a byte buffer of the appropriate length var intPtr = new IntPtr(pPoints); var pointData = NSData.FromBytes(intPtr, (System.nuint)(stride * points.Length)); // Create a geometry source (factory) configured properly for the data (3 vertices) var source = SCNGeometrySource.FromData( pointData, SCNGeometrySourceSemantics.Vertex, points.Length, true, 3, sizeof(float), 0, stride ); // Don't unpin yet, because geometry creation is lazy // Create geometry element // The null and bytesPerElement = 0 look odd, but this is just a template object var element = SCNGeometryElement.FromData(null, SCNGeometryPrimitiveType.Point, points.Length, 0); element.PointSize = 0.001F; element.MinimumPointScreenSpaceRadius = size; element.MaximumPointScreenSpaceRadius = size; // Stitch the data (source) together with the template (element) to create the new object var pointsGeometry = SCNGeometry.Create(new[] { source }, new[] { element }); pointsGeometry.Materials = new[] { Utilities.Material(color) }; return(pointsGeometry); } } }
static SCNGeometryElement CreatePlane(nfloat width, nfloat height) { var data = NSData.FromArray(new byte [] { 0, 1, 2, 0, 2, 3 }); return(SCNGeometryElement.FromData(data, SCNGeometryPrimitiveType.Triangles, 2, 1)); }
static internal SCNGeometryElement CreateLines(nfloat width, nfloat height) { var data = NSData.FromArray(new byte [] { 0, 1, 1, 2, 2, 3, 3, 0 }); return(SCNGeometryElement.FromData(data, SCNGeometryPrimitiveType.Line, 4, 1)); }
public static NSObject FromSources(SCNGeometrySource [] sources, SCNGeometryElement [] elements) { return Create (sources, elements); }
public ClothSimMetalNode(IMTLDevice device, uint width, uint height) { var vector3Size = System.Runtime.InteropServices.Marshal.SizeOf <OpenTK.NVector3>(); var vertices = new List <SCNVector3>(); var normals = new List <SCNVector3>(); var uvs = new List <OpenTK.Vector2>(); var indices = new List <byte>(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var p = new SCNVector3(x, 0, y); vertices.Add(p); normals.Add(SCNVector3.UnitY); uvs.Add(new OpenTK.Vector2(p.X / width, p.Z / height)); } } for (var y = 0; y < (height - 1); y++) { for (var x = 0; x < (width - 1); x++) { // make 2 triangles from the 4 vertices of a quad var i0 = (byte)(y * width + x); var i1 = (byte)(i0 + 1); var i2 = (byte)(i0 + width); var i3 = (byte)(i2 + 1); // triangle 1 indices.Add(i0); indices.Add(i2); indices.Add(i3); // triangle 2 indices.Add(i0); indices.Add(i3); indices.Add(i1); } } var vertexBuffer1 = device.CreateBuffer(vertices.ToArray(), MTLResourceOptions.CpuCacheModeWriteCombined); var vertexBuffer2 = device.CreateBuffer((nuint)(vertices.Count * vector3Size), MTLResourceOptions.CpuCacheModeWriteCombined); var vertexSource = SCNGeometrySource.FromMetalBuffer(vertexBuffer1, MTLVertexFormat.Float3, SCNGeometrySourceSemantics.Vertex, vertices.Count, 0, vector3Size); var normalBuffer = device.CreateBuffer(normals.ToArray(), MTLResourceOptions.CpuCacheModeWriteCombined); var normalWorkBuffer = device.CreateBuffer((nuint)(normals.Count * vector3Size), MTLResourceOptions.CpuCacheModeWriteCombined); var normalSource = SCNGeometrySource.FromMetalBuffer(normalBuffer, MTLVertexFormat.Float3, SCNGeometrySourceSemantics.Normal, normals.Count, 0, vector3Size); var uvBuffer = device.CreateBuffer(uvs.ToArray(), MTLResourceOptions.CpuCacheModeWriteCombined); var uvSource = SCNGeometrySource.FromMetalBuffer(uvBuffer, MTLVertexFormat.Float2, SCNGeometrySourceSemantics.Texcoord, uvs.Count, 0, OpenTK.Vector2.SizeInBytes); var data = NSData.FromArray(indices.ToArray()); var indexElement = SCNGeometryElement.FromData(data, SCNGeometryPrimitiveType.Triangles, 1178, 4); var geometry = SCNGeometry.Create(new SCNGeometrySource[] { vertexSource, normalSource, uvSource }, new SCNGeometryElement[] { indexElement }); // velocity buffers var velocityBuffer1 = device.CreateBuffer((nuint)(vertices.Count * vector3Size), MTLResourceOptions.CpuCacheModeWriteCombined); var velocityBuffer2 = device.CreateBuffer((nuint)(vertices.Count * vector3Size), MTLResourceOptions.CpuCacheModeWriteCombined); this.Geometry = geometry; this.VertexCount = vertices.Count; this.Vb1 = vertexBuffer1; this.Vb2 = vertexBuffer2; this.NormalBuffer = normalBuffer; this.NormalWorkBuffer = normalWorkBuffer; this.VelocityBuffers = new List <IMTLBuffer> { velocityBuffer1, velocityBuffer2 }; }