コード例 #1
0
        private (SCNNode, float) FindAttachNodeNearPoint(SCNNode system, SCNNode node, SCNVector3 point, float tolerance)
        {
            var     currentTolerance   = tolerance;
            SCNNode currentClosestNode = null;

            // if this object has a socket node near ball node, then use it
            if (!string.IsNullOrEmpty(node.Name) &&
                node.Name.StartsWith((ConstrainHierarchyComponent.SocketName), StringComparison.Ordinal))
            {
                var attachOffset = node.ConvertPositionToNode(SCNVector3.Zero, system);
                var distance     = (point - attachOffset).Length;
                if (distance < currentTolerance)
                {
                    currentTolerance   = distance;
                    currentClosestNode = node;
                }
            }

            foreach (var child in node.ChildNodes)
            {
                var(socketNode, distance) = FindAttachNodeNearPoint(system, child, point, currentTolerance);
                if (socketNode != null)
                {
                    currentTolerance   = distance;
                    currentClosestNode = socketNode;
                }
            }

            return(currentClosestNode, currentTolerance);
        }
コード例 #2
0
        public void CheckIfObjectShouldMoveOntoPlane(ARPlaneAnchor anchor, SCNNode planeAnchorNode)
        {
            foreach (var vo in VirtualObjects)
            {
                // Get the object's position in the plane's coordinate system.
                var objectPos = planeAnchorNode.ConvertPositionToNode(vo.Position, vo.ParentNode);

                if (Math.Abs(objectPos.Y) < float.Epsilon)
                {
                    return;                     // The object is already on the plane - nothing to do here.
                }

                // Add 10% tolerance to the corners of the plane.
                var tolerance = 0.1f;

                var minX = anchor.Center.X - anchor.Extent.X / 2f - anchor.Extent.X * tolerance;
                var maxX = anchor.Center.X + anchor.Extent.X / 2f + anchor.Extent.X * tolerance;
                var minZ = anchor.Center.Z - anchor.Extent.Z / 2f - anchor.Extent.Z * tolerance;
                var maxZ = anchor.Center.Z + anchor.Extent.Z / 2f + anchor.Extent.Z * tolerance;

                if (objectPos.X < minX || objectPos.X > maxX || objectPos.Z < minZ || objectPos.Z > maxZ)
                {
                    return;
                }

                // Drop the object onto the plane if it is near it.
                var verticalAllowance = 0.05f;
                var epsilon           = 0.001;       // Do not bother updating if the difference is less than a mm.
                var distanceToPlane   = Math.Abs(objectPos.Y);
                if (distanceToPlane > epsilon && distanceToPlane < verticalAllowance)
                {
                    Delegate.DidMoveObjectOntoNearbyPlane(this, vo);

                    SCNTransaction.Begin();
                    SCNTransaction.AnimationDuration       = distanceToPlane * 500;               // Move 2mm per second
                    SCNTransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
                    vo.Position = new SCNVector3(vo.Position.X, anchor.Transform.M32, vo.Position.Z);
                    SCNTransaction.Commit();
                }
            }
        }
コード例 #3
0
        private SCNNode SetupVehicle(SCNScene scene)
        {
            var carScene    = SCNScene.FromFile("rc_car", ResourceManager.ResourceFolder, (NSDictionary)null);
            var chassisNode = carScene.RootNode.FindChildNode("rccarBody", false);

            chassisNode.Position = new SCNVector3(0f, 10f, 30f);
            chassisNode.Rotation = new SCNVector4(0f, 1f, 0f, (float)Math.PI);

            var body = SCNPhysicsBody.CreateDynamicBody();

            body.AllowsResting   = false;
            body.Mass            = 80f;
            body.Restitution     = 0.1f;
            body.Friction        = 0.5f;
            body.RollingFriction = 0f;

            chassisNode.PhysicsBody = body;

            var frontCameraNode = SCNNode.Create();

            frontCameraNode.Position    = new SCNVector3(0f, 3.5f, 2.5f);
            frontCameraNode.Rotation    = new SCNVector4(0f, 1f, 0f, (float)Math.PI);
            frontCameraNode.Camera      = SCNCamera.Create();
            frontCameraNode.Camera.XFov = 75f;
            frontCameraNode.Camera.ZFar = 500f;

            chassisNode.AddChildNode(frontCameraNode);

            scene.RootNode.AddChildNode(chassisNode);

            var pipeNode = chassisNode.FindChildNode("pipe", true);

            reactor = SCNParticleSystem.Create("reactor", ResourceManager.ResourceFolder);
            reactor.ParticleImage   = ResourceManager.GetResourcePath("spark.png");
            reactorDefaultBirthRate = reactor.BirthRate;
            reactor.BirthRate       = 0;
            pipeNode.AddParticleSystem(reactor);

            SCNNode wheel0Node = chassisNode.FindChildNode("wheelLocator_FL", true);
            SCNNode wheel1Node = chassisNode.FindChildNode("wheelLocator_FR", true);
            SCNNode wheel2Node = chassisNode.FindChildNode("wheelLocator_RL", true);
            SCNNode wheel3Node = chassisNode.FindChildNode("wheelLocator_RR", true);

            var wheel0 = SCNPhysicsVehicleWheel.Create(wheel0Node);
            var wheel1 = SCNPhysicsVehicleWheel.Create(wheel1Node);
            var wheel2 = SCNPhysicsVehicleWheel.Create(wheel2Node);
            var wheel3 = SCNPhysicsVehicleWheel.Create(wheel3Node);

            var min = SCNVector3.Zero;
            var max = SCNVector3.Zero;

            wheel0Node.GetBoundingBox(ref min, ref max);
            float wheelHalfWidth = 0.5f * (max.X - min.X);

            wheel0.ConnectionPosition = SCNVector3.Add(wheel0Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel1.ConnectionPosition = SCNVector3.Subtract(wheel1Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel2.ConnectionPosition = SCNVector3.Add(wheel2Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));
            wheel3.ConnectionPosition = SCNVector3.Subtract(wheel3Node.ConvertPositionToNode(SCNVector3.Zero, chassisNode), new SCNVector3(wheelHalfWidth, 0f, 0f));

            var vehicle = SCNPhysicsVehicle.Create(chassisNode.PhysicsBody,
                                                   new SCNPhysicsVehicleWheel[] { wheel0, wheel1, wheel2, wheel3 });

            scene.PhysicsWorld.AddBehavior(vehicle);
            this.vehicle = vehicle;

            return(chassisNode);
        }