예제 #1
0
        private void PresentPrimitives(PresentationViewController presentationViewController)
        {
            var count  = 100;
            var spread = 0.0f;

            // create a cube with a sphere shape
            for (int i = 0; i < count; ++i)
            {
                var model = SCNNode.Create();
                model.Position    = GroundNode.ConvertPositionToNode(new SCNVector3(RandFloat(-1, 1), RandFloat(30, 50), RandFloat(-1, 1)), null);
                model.EulerAngles = new SCNVector3(RandFloat(0, NMath.PI * 2), RandFloat(0, NMath.PI * 2), RandFloat(0, NMath.PI * 2));

                var size          = new SCNVector3(RandFloat(1.0, 1.5), RandFloat(1.0, 1.5), RandFloat(1.0, 1.5));
                var random        = new Random((int)DateTime.Now.Ticks);
                int geometryIndex = random.Next(0, 7);
                switch (geometryIndex)
                {
                case 0:                 // Box
                    model.Geometry = SCNBox.Create(size.X, size.Y, size.Z, 0);
                    break;

                case 1:                 // Pyramid
                    model.Geometry = SCNPyramid.Create(size.X, size.Y, size.Z);
                    break;

                case 2:                 // Sphere
                    model.Geometry = SCNSphere.Create(size.X);
                    break;

                case 3:                 // Cylinder
                    model.Geometry = SCNCylinder.Create(size.X, size.Y);
                    break;

                case 4:                 // Tube
                    model.Geometry = SCNTube.Create(size.X, size.X + size.Z, size.Y);
                    break;

                case 5:                 // Capsule
                    model.Geometry = SCNCapsule.Create(size.X, size.Y + 2 * size.X);
                    break;

                case 6:                 // Torus
                    model.Geometry = SCNTorus.Create(size.X, NMath.Min(size.X, size.Y) / 2);
                    break;

                default:
                    break;
                }

                model.Geometry.FirstMaterial.Multiply.Contents = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/texture", "png"));

                model.PhysicsBody                 = SCNPhysicsBody.CreateDynamicBody();
                model.PhysicsBody.Velocity        = new SCNVector3(RandFloat(-spread, spread), -10, RandFloat(-spread, spread));
                model.PhysicsBody.AngularVelocity = new SCNVector4(RandFloat(-1, 1), RandFloat(-1, 1), RandFloat(-1, 1), RandFloat(-3, 3));

                Shapes.Add(model);

                ((SCNView)presentationViewController.View).Scene.RootNode.AddChildNode(model);
            }
        }
예제 #2
0
 public void CreateTrees()
 {
     tree                 = SCNPyramid.Create(23, 60, 23);
     treeNode             = SCNNode.FromGeometry(tree);
     treeNode.Position    = new SCNVector3(0, 0, 0);
     treeNode.CastsShadow = true;
     gameScene.RootNode.AddChildNode(treeNode);
 }
예제 #3
0
        private void AddPyramid()
        {
            SCNNode pyramidNode = new SCNNode();

            pyramidNode.Geometry = SCNPyramid.Create(0.05f, 0.05f, 0.05f);
            pyramidNode.Geometry.FirstMaterial.Diffuse.Contents  = UIColor.Magenta; //Color del objeto
            pyramidNode.Geometry.FirstMaterial.Specular.Contents = UIColor.White;   //Color del reflejo
            pyramidNode.Position = new SCNVector3(0.1f, 0, 0.1f);

            sceneView.Scene.RootNode.AddChildNode(pyramidNode);
        }
예제 #4
0
        SCNGeometry CreateGeometry(float width, float height, float length, UIColor color)
        {
            SCNMaterial material = new SCNMaterial();

            material.Diffuse.Contents = color;

            SCNPyramid geometry = SCNPyramid.Create(width, height, length);

            geometry.Materials = new[] { material };

            return(geometry);
        }
예제 #5
0
        private void AddHouse()
        {
            var pyramidNode = new SCNNode();

            pyramidNode.Geometry = SCNPyramid.Create(0.1f, 0.1f, 0.1f);
            pyramidNode.Geometry.FirstMaterial.Diffuse.Contents = UIColor.Red;
            pyramidNode.Position = new SCNVector3(0, 0, -0.2f);
            sceneView.Scene.RootNode.AddChildNode(pyramidNode);

            var boxNode = new SCNNode();

            boxNode.Geometry = SCNBox.Create(0.1f, 0.1f, 0.1f, 0);
            boxNode.Geometry.FirstMaterial.Diffuse.Contents = UIColor.Blue;
            boxNode.Position = new SCNVector3(0, -0.05f, 0);
            pyramidNode.AddChildNode(boxNode);

            var door = new SCNNode();

            door.Geometry = SCNPlane.Create(0.03f, 0.06f);
            door.Geometry.FirstMaterial.Diffuse.Contents = UIColor.Brown;
            door.Position = new SCNVector3(0, -0.02f, 0.051f);
            boxNode.AddChildNode(door);

            var window1 = new SCNNode();

            window1.Geometry = SCNPlane.Create(0.02f, 0.02f);
            window1.Geometry.FirstMaterial.Diffuse.Contents = UIColor.White;
            window1.Position = new SCNVector3(0.03f, 0.025f, 0.051f);
            boxNode.AddChildNode(window1);

            var window2 = new SCNNode();

            window2.Geometry = SCNPlane.Create(0.02f, 0.02f);
            window2.Geometry.FirstMaterial.Diffuse.Contents = UIColor.White;
            window2.Position = new SCNVector3(-0.03f, 0.025f, 0.051f);
            boxNode.AddChildNode(window2);
        }
예제 #6
0
        // Create a carousel of 3D primitives
        private void PresentPrimitives()
        {
            // Create the carousel node. It will host all the primitives as child nodes.
            CarouselNode          = SCNNode.Create();
            CarouselNode.Position = new SCNVector3(0, 0.1f, -5);
            CarouselNode.Scale    = new SCNVector3(0, 0, 0);           // start infinitely small
            ContentNode.AddChildNode(CarouselNode);

            // Animate the scale to achieve a "grow" effect
            SCNTransaction.Begin();
            SCNTransaction.AnimationDuration = 1;
            CarouselNode.Scale = new SCNVector3(1, 1, 1);
            SCNTransaction.Commit();

            // Rotate the carousel forever
            var rotationAnimation = CABasicAnimation.FromKeyPath("rotation");

            rotationAnimation.Duration    = 40.0f;
            rotationAnimation.RepeatCount = float.MaxValue;
            rotationAnimation.To          = NSValue.FromVector(new SCNVector4(0, 1, 0, (float)Math.PI * 2));
            CarouselNode.AddAnimation(rotationAnimation, new NSString("rotationAnimation"));

            // A material shared by all the primitives
            var sharedMaterial = SCNMaterial.Create();

            sharedMaterial.Reflective.Contents  = new NSImage(NSBundle.MainBundle.PathForResource("SharedTextures/envmap", "jpg"));
            sharedMaterial.Reflective.Intensity = 0.2f;
            sharedMaterial.DoubleSided          = true;

            PrimitiveIndex = 0;

            // SCNBox
            var box = SCNBox.Create(5.0f, 5.0f, 5.0f, 5.0f * 0.05f);

            box.WidthSegmentCount   = 4;
            box.HeightSegmentCount  = 4;
            box.LengthSegmentCount  = 4;
            box.ChamferSegmentCount = 4;
            AddPrimitive(box, 5.0f / 2, rotationAnimation, sharedMaterial);

            // SCNPyramid
            var pyramid = SCNPyramid.Create(5.0f * 0.8f, 5.0f, 5.0f * 0.8f);

            pyramid.WidthSegmentCount  = 4;
            pyramid.HeightSegmentCount = 10;
            pyramid.LengthSegmentCount = 4;
            AddPrimitive(pyramid, 0, rotationAnimation, sharedMaterial);

            // SCNCone
            var cone = SCNCone.Create(0, 5.0f / 2, 5.0f);

            cone.RadialSegmentCount = 20;
            cone.HeightSegmentCount = 4;
            AddPrimitive(cone, 5.0f / 2, rotationAnimation, sharedMaterial);

            // SCNTube
            var tube = SCNTube.Create(5.0f * 0.25f, 5.0f * 0.5f, 5.0f);

            tube.HeightSegmentCount = 5;
            tube.RadialSegmentCount = 40;
            AddPrimitive(tube, 5.0f / 2, rotationAnimation, sharedMaterial);

            // SCNCapsule
            var capsule = SCNCapsule.Create(5.0f * 0.4f, 5.0f * 1.4f);

            capsule.HeightSegmentCount = 5;
            capsule.RadialSegmentCount = 20;
            AddPrimitive(capsule, 5.0f * 0.7f, rotationAnimation, sharedMaterial);

            // SCNCylinder
            var cylinder = SCNCylinder.Create(5.0f * 0.5f, 5.0f);

            cylinder.HeightSegmentCount = 5;
            cylinder.RadialSegmentCount = 40;
            AddPrimitive(cylinder, 5.0f / 2, rotationAnimation, sharedMaterial);

            // SCNSphere
            var sphere = SCNSphere.Create(5.0f * 0.5f);

            sphere.SegmentCount = 20;
            AddPrimitive(sphere, 5.0f / 2, rotationAnimation, sharedMaterial);

            // SCNTorus
            var torus = SCNTorus.Create(5.0f * 0.5f, 5.0f * 0.25f);

            torus.RingSegmentCount = 40;
            torus.PipeSegmentCount = 20;
            AddPrimitive(torus, 5.0f / 4, rotationAnimation, sharedMaterial);

            // SCNPlane
            var plane = SCNPlane.Create(5.0f, 5.0f);

            plane.WidthSegmentCount  = 5;
            plane.HeightSegmentCount = 5;
            plane.CornerRadius       = 5.0f * 0.1f;
            AddPrimitive(plane, 5.0f / 2, rotationAnimation, sharedMaterial);
        }
예제 #7
0
        private void BuildVisualizationsOfNode(SCNNode node, ref SCNNode verticesNode, ref SCNNode normalsNode)
        {
            // A material that will prevent the nodes from being lit
            var noLightingMaterial = SCNMaterial.Create();

            noLightingMaterial.LightingModelName = SCNLightingModel.Constant;

            var normalMaterial = SCNMaterial.Create();

            normalMaterial.LightingModelName = SCNLightingModel.Constant;
            normalMaterial.Diffuse.Contents  = NSColor.Red;

            // Create nodes to represent the vertex and normals
            var positionVisualizationNode = SCNNode.Create();
            var normalsVisualizationNode  = SCNNode.Create();

            // Retrieve the vertices and normals from the model
            var positionSource = node.Geometry.GetGeometrySourcesForSemantic(SCNGeometrySourceSemantic.Vertex) [0];
            var normalSource   = node.Geometry.GetGeometrySourcesForSemantic(SCNGeometrySourceSemantic.Normal) [0];

            // Get vertex and normal bytes
            var vertexBufferByte = (byte[])positionSource.Data.ToArray();
            var vertexBuffer     = new float[vertexBufferByte.Length / 4];

            Buffer.BlockCopy(vertexBufferByte, 0, vertexBuffer, 0, vertexBufferByte.Length);

            var normalBufferByte = (byte[])normalSource.Data.ToArray();
            var normalBuffer     = new float[normalBufferByte.Length / 4];

            Buffer.BlockCopy(normalBufferByte, 0, normalBuffer, 0, normalBufferByte.Length);

            // Iterate and create geometries to represent the positions and normals
            for (var i = 0; i < positionSource.VectorCount; i++)
            {
                // One new node per normal/vertex
                var vertexNode = SCNNode.Create();
                var normalNode = SCNNode.Create();

                // Attach one sphere per vertex
                var sphere = SCNSphere.Create(0.5f);
                sphere.SegmentCount  = 4;                // use a small segment count for better performances
                sphere.FirstMaterial = noLightingMaterial;
                vertexNode.Geometry  = sphere;

                // And one pyramid per normal
                var pyramid = SCNPyramid.Create(0.1f, 0.1f, 8);
                pyramid.FirstMaterial = normalMaterial;
                normalNode.Geometry   = pyramid;

                // Place the position node
                var componentsPerVector = positionSource.ComponentsPerVector;
                vertexNode.Position = new SCNVector3(vertexBuffer [i * componentsPerVector], vertexBuffer [i * componentsPerVector + 1], vertexBuffer [i * componentsPerVector + 2]);

                // Place the normal node
                normalNode.Position = vertexNode.Position;

                // Orientate the normal
                var up         = new Vector3(0, 0, 1);
                var normalVec  = new Vector3(normalBuffer [i * 3], normalBuffer [i * 3 + 1], normalBuffer [i * 3 + 2]);
                var axis       = Vector3.Normalize(Vector3.Cross(up, normalVec));
                var dotProduct = Vector3.Dot(up, normalVec);
                normalNode.Rotation = new SCNVector4(axis.X, axis.Y, axis.Z, NMath.Acos(dotProduct));

                // Add the nodes to their parent
                positionVisualizationNode.AddChildNode(vertexNode);
                normalsVisualizationNode.AddChildNode(normalNode);
            }

            // We must flush the transaction in order to make sure that the parametric geometries (sphere and pyramid)
            // are up-to-date before flattening the nodes
            SCNTransaction.Flush();

            // Flatten the visualization nodes so that they can be rendered with 1 draw call
            verticesNode = positionVisualizationNode.FlattenedClone();
            normalsNode  = normalsVisualizationNode.FlattenedClone();
        }