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 static SCNGeometrySource Create(List <SCNVector4> colors)
        {
            SCNGeometrySource result = null;

            unsafe
            {
                var bytes       = new List <byte>();
                var colorsArray = colors.ToArray();

                for (int i = 0; i < colors.Count; i++)
                {
                    fixed(SCNVector4 *point = &colorsArray[i])
                    {
                        var intPtr = new IntPtr(point);
                        var data   = NSData.FromBytes(intPtr, (nuint)SCNVector4.SizeInBytes);

                        bytes.AddRange(data.ToList());
                    }
                }

                var colorData = NSData.FromArray(bytes.ToArray());
                result = SCNGeometrySource.FromData(colorData,
                                                    SCNGeometrySourceSemantics.Color,
                                                    colors.Count,
                                                    true,
                                                    4,
                                                    sizeof(float),
                                                    0,
                                                    SCNVector4.SizeInBytes);
            }

            return(result);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        public void FromMetalBuffer()
        {
            if (!TestRuntime.CheckXcodeVersion(7, 0))
            {
                Assert.Ignore("Requires iOS 9.0 or macOS 10.11");
            }
#if !MONOMAC
            if (Runtime.Arch != Arch.DEVICE)
            {
                Assert.Inconclusive("Metal tests only works on device so far");
            }
#endif

            var device = MTLDevice.SystemDefault;
            if (device == null)
            {
                Assert.Inconclusive("Device does not support Metal");
            }

            using (var buffer = device.CreateBuffer(1024, MTLResourceOptions.CpuCacheModeDefault)) {
                using (var source = SCNGeometrySource.FromMetalBuffer(buffer, MTLVertexFormat.Char2, SCNGeometrySourceSemantic.Vertex, 36, 0, 0)) {
                    // the fact that it works means the lack of respondToSelector (in introspection tests) is no
                    // big deal and that the API really exists
                    Assert.NotNull(source);
                }
            }
        }
Esempio n. 5
0
        public void SCNGeometrySource_BoneStringTests()          // These were radar://17782603
        {
            Asserts.EnsureYosemite();

#pragma warning disable 0219
            SCNGeometrySource d = SCNGeometrySource.FromData(new NSData(), SCNGeometrySourceSemantic.BoneWeights, 1, false, 1, 1, 1, 1);
            d = SCNGeometrySource.FromData(new NSData(), SCNGeometrySourceSemantic.BoneIndices, 1, false, 1, 1, 1, 1);
#pragma warning restore 0219
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        public void SCNGeometrySource_FromDataTest()
        {
            Asserts.EnsureMountainLion();
#pragma warning disable 0219
            SCNGeometrySource d = SCNGeometrySource.FromData(new NSData(), SCNGeometrySourceSemantic.Color, 1, false, 1, 1, 1, 1);
            foreach (SCNGeometrySourceSemantics s in Enum.GetValues(typeof(SCNGeometrySourceSemantics)))
            {
                if (!isValidEnumForPlatform(s))
                {
                    continue;
                }
                d = SCNGeometrySource.FromData(new NSData(), s, 1, false, 1, 1, 1, 1);
            }
#pragma warning restore 0219
        }
Esempio n. 9
0
        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);
                }
            }
        }
Esempio n. 10
0
 static internal SCNGeometrySource [] CreateGeometrySources(nfloat width, nfloat height)
 {
     return(new [] {
         SCNGeometrySource.FromVertices(new [] {
             new SCNVector3(0, 0, 0),
             new SCNVector3(0, height, 0),
             new SCNVector3(width, height, 0),
             new SCNVector3(width, 0, 0)
         }),
         SCNGeometrySource.FromNormals(new [] {
             new SCNVector3(0, 0, 1),
             new SCNVector3(0, 0, 1),
             new SCNVector3(0, 0, 1),
             new SCNVector3(0, 0, 1)
         }),
         SCNGeometrySource.FromTextureCoordinates(new [] {
             new CGPoint(0, 0),
             new CGPoint(0, 1),
             new CGPoint(1, 1),
             new CGPoint(1, 0)
         })
     });
 }
Esempio n. 11
0
        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
            };
        }