示例#1
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);
        }
    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 }));
    }
示例#3
0
 static SCNGeometry CreateGeometry(nfloat width, nfloat height)
 => SCNGeometry.Create(
     CreateGeometrySources(width, height),
     new [] {
     CreatePlane(width, height),
     CreatePlane(width, height),
     CreateLines(width, height)
 });
示例#4
0
        public static void UpdateGeometry(this SCNNode node, SCNGeometry geometry)
        {
            var oldGeometry = node.Geometry;

            node.Geometry = geometry;

            oldGeometry.Dispose();
            oldGeometry = null;
        }
        public SCNPhysicsBody CreatePlanePhysics(SCNGeometry geometry)
        {
            var body = SCNPhysicsBody.CreateStaticBody();

            body.PhysicsShape = SCNPhysicsShape.Create(geometry, new NSDictionary());
            body.Restitution  = 0.5f;
            body.Friction     = 0.5f;

            return(body);
        }
示例#6
0
        public PlayerCharacter(SCNNode characterNode) : base(characterNode)
        {
            CategoryBitMask   = NodeCategory.Lava;
            velocity          = SCNVector3.Zero;
            IsWalking         = false;
            changingDirection = false;
            baseWalkSpeed     = 0.0167f;
            JumpBoost         = 0.0f;

            WalkSpeed           = baseWalkSpeed * 2;
            Jumping             = false;
            groundPlaneHeight   = 0.0f;
            playerWalkDirection = WalkDirection.Right;

            cameraHelper = new SCNNode {
                Position = new SCNVector3(1000f, 200f, 0f)
            };

            AddChildNode(cameraHelper);

            CollideSphere = new SCNNode {
                Position = new SCNVector3(0f, 80f, 0f)
            };

            SCNGeometry     geo    = SCNCapsule.Create(90f, 160f);
            SCNPhysicsShape shape2 = SCNPhysicsShape.Create(geo, (NSDictionary)null);

            CollideSphere.PhysicsBody = SCNPhysicsBody.CreateBody(SCNPhysicsBodyType.Kinematic, shape2);

            CollideSphere.PhysicsBody.CollisionBitMask =
                GameCollisionCategory.Banana |
                GameCollisionCategory.Coin |
                GameCollisionCategory.Coconut |
                GameCollisionCategory.Lava;

            CollideSphere.PhysicsBody.CategoryBitMask = GameCollisionCategory.Player;
            AddChildNode(CollideSphere);

            DustPoof = GameSimulation.LoadParticleSystemWithName("dust");
            NSString artResourcePath = (NSString)GameSimulation.PathForArtResource("level/effects/effects_transparent.png");

            DustPoof.ParticleImage    = artResourcePath;
            DustWalking               = GameSimulation.LoadParticleSystemWithName("dustWalking");
            DustWalking.ParticleImage = artResourcePath;
            dustWalkingBirthRate      = DustWalking.BirthRate;

            // Load the animations and store via a lookup table.
            SetupIdleAnimation();
            SetupRunAnimation();
            SetupJumpAnimation();
            SetupBoredAnimation();
            SetupHitAnimation();

            PlayIdle();
        }
示例#7
0
        public SCNPhysicsBody MakePhysicsBody(SCNGeometry geometry)
        {
            var option = new SCNPhysicsShapeOptions();

            option.KeepAsCompound = true;
            option.ShapeType      = SCNPhysicsShapeType.ConcavePolyhedron;

            var shape = SCNPhysicsShape.Create(geometry, option);

            return(SCNPhysicsBody.CreateBody(type: SCNPhysicsBodyType.Static, shape));
        }
示例#8
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);
        }
        public override SCNPhysicsBody CreatePlanePhysics(SCNGeometry geometry)
        {
            var body = SCNPhysicsBody.CreateStaticBody();

            body.PhysicsShape = SCNPhysicsShape.Create(geometry, new SCNPhysicsShapeOptions {
                ShapeType = SCNPhysicsShapeType.BoundingBox
            });
            body.Restitution = 0.5f;
            body.Friction    = 0.5f;

            return(body);
        }
示例#10
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);
            }
        }
示例#11
0
        public static void SetupPaintColorMask(this SCNGeometry geometry, string name)
        {
            // if we've already set it up, don't do it again
            if (geometry.ValueForKey(new NSString(PaintMaskColorKey)) == null)
            {
                if (PaintColorMaskTextures.TryGetValue(name, out string paintMask))
                {
                    // all textures are absolute paths from the app folder
                    var texturePath = $"art.scnassets/textures/{paintMask}.ktx";

                    if (name.Contains("catapult"))
                    {
                        //os_log(.debug, "visited %s for texture", name)
                    }

                    var surfaceScript = @"
                    #pragma arguments

                    texture2d<float> paintMaskTexture;
                    //sampler paintMaskSampler;
                    float4 paintMaskColor;

                    #pragma body

                    // 0 is use diffuse texture.rgb, 1 is use paintMaskColor.rgb
                    float paintMaskSelector = paintMaskTexture.sample(
                        sampler(filter::linear), // paintMaskSampler,
                        _surface.diffuseTexcoord.xy).r;

                    _surface.diffuse.rgb = mix(_surface.diffuse.rgb, paintMaskColor.rgb, paintMaskSelector);
                    ";

                    geometry.ShaderModifiers = new SCNShaderModifiers()
                    {
                        EntryPointSurface = surfaceScript
                    };

                    // mask pro
                    var prop = SCNMaterialProperty.Create(new NSString(texturePath));
                    prop.MinificationFilter  = SCNFilterMode.Linear;
                    prop.MagnificationFilter = SCNFilterMode.Nearest;
                    prop.MipFilter           = SCNFilterMode.Nearest;
                    prop.MaxAnisotropy       = 1;

                    // set the uniforms, these will be overridden in the runtime
                    geometry.SetTexture("paintMaskTexture", prop);
                    geometry.SetFloat4(PaintMaskColorKey, SCNVector4.One);
                }
            }
        }
示例#12
0
        private SCNNode CreateBlock(SCNVector3 position, SCNVector3 size)
        {
            if (DiceMesh == null)
            {
                DiceMesh = CreateBlockMesh(size);
            }

            var model = SCNNode.Create();

            model.Position    = position;
            model.Geometry    = DiceMesh;
            model.PhysicsBody = SCNPhysicsBody.CreateDynamicBody();

            return(model);
        }
示例#13
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);
                }
            }
        }
示例#14
0
        private void AddPrimitive(SCNGeometry geometry, float yPos, CABasicAnimation rotationAnimation, SCNMaterial sharedMaterial)
        {
            var xPos = 13.0f * (float)Math.Sin((float)Math.PI * 2 * PrimitiveIndex / 9.0f);
            var zPos = 13.0f * (float)Math.Cos((float)Math.PI * 2 * PrimitiveIndex / 9.0f);

            var node = SCNNode.Create();

            node.Position = new SCNVector3(xPos, yPos, zPos);
            node.Geometry = geometry;
            node.Geometry.FirstMaterial = sharedMaterial;
            CarouselNode.AddChildNode(node);

            PrimitiveIndex++;
            rotationAnimation.TimeOffset = -PrimitiveIndex;
            node.AddAnimation(rotationAnimation, new NSString("rotationAnimation"));
        }
示例#15
0
        private static void FixNormalMap(this SCNGeometry geometry)
        {
            foreach (var material in geometry.Materials)
            {
                var prop = material.Normal;
                // astc needs gggr and .ag to compress to L+A,
                //   but will compress rg01 to RGB single plane (less quality)
                // bc/eac/explicit/no compression use rg01 and .rg
                //   rg01 is easier to see and edit in texture editors

                // set the normal to RED | GREEN (rg01 compression)
                // uses single plane on ASTC, dual on BC5/EAC_RG11/Explicit
                prop.TextureComponents = SCNColorMask.Red | SCNColorMask.Green;

                // set the normal to ALPHA | GREEN (gggr compression)
                // uses dual plane for ASTC, BC3nm
                // prop.textureComponents = [.alpha, .green]
            }
        }
示例#16
0
        SCNNode CreateTorchNode()
        {
            SCNGeometry geometry = SCNBox.Create(20f, 100f, 20f, 0f);

            geometry.FirstMaterial.Diffuse.Contents = AppKit.NSColor.Brown;
            var template = new SCNNode {
                Geometry = geometry
            };

            var particleEmitter = new SCNNode {
                Position = new SCNVector3(0f, 50f, 0f)
            };

            SCNParticleSystem fire = GameSimulation.LoadParticleSystemWithName("torch", "spark");

            particleEmitter.AddParticleSystem(fire);
            particleEmitter.Light = TorchLight;

            template.AddChildNode(particleEmitter);
            return(template);
        }
示例#17
0
        /// <summary>
        /// must copy geometry and materials to set unique data on both here we only want
        /// </summary>
        public static SCNGeometry CopyGeometryAndMaterials(this SCNGeometry geometry)
        {
            var result = geometry;

            if (geometry.Copy() is SCNGeometry geometryCopy)
            {
                var materialsCopy = new List <SCNMaterial>();
                foreach (var material in geometryCopy.Materials)
                {
                    if (material.Copy() is SCNMaterial materialCopy)
                    {
                        materialsCopy.Add(materialCopy);
                    }
                }

                geometryCopy.Materials = materialsCopy.ToArray();

                result = geometryCopy;
            }

            return(result);
        }
示例#18
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
            };
        }
		private void AddPrimitive (SCNGeometry geometry, float yPos, CABasicAnimation rotationAnimation, SCNMaterial sharedMaterial)
		{
			var xPos = 13.0f * NMath.Sin (NMath.PI * 2 * PrimitiveIndex / 9.0f);
			var zPos = 13.0f * NMath.Cos (NMath.PI * 2 * PrimitiveIndex / 9.0f);

			var node = SCNNode.Create ();
			node.Position = new SCNVector3 (xPos, yPos, zPos);
			node.Geometry = geometry;
			node.Geometry.FirstMaterial = sharedMaterial;
			CarouselNode.AddChildNode (node);

			PrimitiveIndex++;
			rotationAnimation.TimeOffset = -PrimitiveIndex;
			node.AddAnimation (rotationAnimation, new NSString ("rotationAnimation"));
		}
示例#20
0
 // https://developer.apple.com/documentation/scenekit/scnshadable#1654834
 // Some of these can be animated inside of an SCNTransaction.
 // Sets shader modifier data onto a material or all materials in a geometry.
 public static void SetTexture(this SCNGeometry geometry, string uniform, SCNMaterialProperty texture)
 {
     // this must be the texture name, and not the sampler name
     geometry.SetValueForKey(texture, new NSString(uniform));
 }
示例#21
0
		private SCNNode CreateBlock (SCNVector3 position, SCNVector3 size)
		{
			if (DiceMesh == null) {
				DiceMesh = CreateBlockMesh (size);
			}

			var model = SCNNode.Create ();
			model.Position = position;
			model.Geometry = DiceMesh;
			model.PhysicsBody =  SCNPhysicsBody.CreateDynamicBody ();

			return model;
		}
示例#22
0
 public static void SetFloat4(this SCNGeometry geometry, string uniform, SCNVector4 value)
 {
     geometry.SetValueForKey(NSValue.FromVector(value), new NSString(uniform));
 }
示例#23
0
 public static void SetColor(this SCNGeometry geometry, string uniform, UIColor value)
 {
     geometry.SetValueForKey(value, new NSString(uniform));
 }
示例#24
0
 public static bool HasUniform(this SCNGeometry geometry, string uniform)
 {
     return(geometry.ValueForKey(new NSString(uniform)) != null);
 }
示例#25
0
 public static void TileTexture(this SCNGeometry box, int num)
 {
     box.FirstMaterial.Diffuse.WrapS             = SCNWrapMode.Mirror;
     box.FirstMaterial.Diffuse.WrapT             = SCNWrapMode.Mirror;
     box.FirstMaterial.Diffuse.ContentsTransform = SCNMatrix4.Scale(num, num, num);
 }