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); } }
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); }
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); }
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); }
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); }
// 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); }
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(); }