Exemple #1
0
        SCNVector3 MakeThrowPosition(SCNMatrix4 transform)
        {
            var force        = new Vector3(0.0f, 0.0f, -0.3f);
            var rotation     = new SCNVector3(transform.M31, transform.M32, transform.M33);
            var rotatedForce = SCNVector3.Multiply(rotation, force) + new Vector3(0.0f, 0.1f, 0.0f);

            return(new SCNVector3(rotatedForce));
        }
Exemple #2
0
        private void PerformPlaneCollision(List <SimulatedTransform> previousTransforms, float seconds)
        {
            for (var i = this.BoneInset; i < this.simulatedTransforms.Count - this.BoneInset; i++)
            {
                if (!this.simulatedTransforms[i].Dynamic)
                {
                    continue;
                }

                var p = this.simulatedTransforms[i].Position;
                var v = this.simulatedTransforms[i].Velocity;

                // project into the space of the base
                var pM = SCNMatrix4.Identity.SetTranslation((OpenTK.Vector3)p);

                var pLocal = SCNMatrix4.Invert(this.restPoseSpace) * pM;

                if (pLocal.Column3.Z <= CollisionPlane)
                {
                    pLocal.M34 = CollisionPlane;
                    pM         = this.restPoseSpace * pLocal;

                    var pOnPlane = new SCNVector3(pM.Column3.X, pM.Column3.Y, pM.Column3.Z);

                    var blend = new SCNVector3(0.3f, 0.3f, 0.3f);
                    this.simulatedTransforms[i].Position = SimdExtensions.Mix(p, pOnPlane, blend);

                    var correctedVelocity = (this.simulatedTransforms[i].Position - previousTransforms[i].Position) / seconds;
                    correctedVelocity = SCNVector3.Multiply(correctedVelocity, new SCNVector3(0.7f, 0.1f, 0.7f));

                    // verlet integration
                    this.simulatedTransforms[i].Velocity = SimdExtensions.Mix(v, correctedVelocity, blend);

                    p = this.simulatedTransforms[i].Position;
                    v = this.simulatedTransforms[i].Velocity;
                }

                if (pLocal.Column3.Y <= CollisionPlane + 0.3f)
                {
                    pLocal.M24 = CollisionPlane + 0.3f;
                    pM         = this.restPoseSpace * pLocal;

                    var pOnPlane = new SCNVector3(pM.Column3.X, pM.Column3.Y, pM.Column3.Z);

                    var blend = new SCNVector3(0.3f, 0.3f, 0.3f);
                    this.simulatedTransforms[i].Position = SimdExtensions.Mix(p, pOnPlane, blend);

                    var correctedVelocity = (this.simulatedTransforms[i].Position - previousTransforms[i].Position) / seconds;

                    // verlet integration
                    this.simulatedTransforms[i].Velocity = SimdExtensions.Mix(v, correctedVelocity, blend);
                }
            }
        }
Exemple #3
0
        public override void Update(double deltaTime)
        {
            SCNMatrix4 mtx         = Transform;
            var        gravity     = new SCNVector3(0f, -90f, 0f);
            var        gravitystep = SCNVector3.Multiply(gravity, (nfloat)deltaTime);

            velocity = SCNVector3.Add(velocity, gravitystep);
            var minMovement = new SCNVector3(0f, -50f, 0f);
            var maxMovement = new SCNVector3(100f, 100f, 100f);

            velocity          = MathUtils.GetMaxVector(velocity, minMovement);
            velocity          = MathUtils.GetMinVector(velocity, maxMovement);
            mtx               = mtx.TranslateWithVector(velocity);
            groundPlaneHeight = GetGroundHeight(mtx);

            if (mtx.M42 < groundPlaneHeight)
            {
                if (!Launching && velocity.Y < 0.0f)
                {
                    if (Jumping)
                    {
                        Jumping = false;
                        if (DustPoof != null)
                        {
                            AddParticleSystem(DustPoof);
                            DustPoof.Loops = false;
                        }
                        PlayLand();
                        JumpBoost = 0.0f;
                    }
                }
                // tie to ground
                mtx.M42 = groundPlaneHeight;

                velocity.Y = 0.0f;
            }

            Transform = mtx;
            //-- move the camera
            SCNNode camera = GameSimulation.Sim.GameLevel.Camera.ParentNode;

            if (camera != null)
            {
                nfloat x = Position.X + ((PlayerWalkDirection == WalkDirection.Right) ? 250 : -250);
                nfloat y = (Position.Y + 261) - (0.85f * (Position.Y - groundPlaneHeight));
                nfloat z = Position.Z + 1500;

                var pos = new SCNVector3(x, y, z);

                SCNMatrix4 desiredTransform = camera.Transform.SetPosition(pos);
                camera.Transform = MathUtils.Interpolate(camera.Transform, desiredTransform, 0.025f);
            }
        }
 partial void DidScale(UIPinchGestureRecognizer gesture)
 {
     if (this.virtualObject != null && gesture.State == UIGestureRecognizerState.Changed)
     {
         var newScale = SCNVector3.Multiply(this.virtualObject.Scale, (float)gesture.Scale);
         this.virtualObject.Scale = newScale;
         gesture.Scale            = 1f;
         // Realistic reflections require an environment probe extent based on the size of the object,
         // so update the environment probe when the object is resized.
         this.requiresProbeRefresh = true;
     }
 }
Exemple #5
0
        public static SCNNode SCAddChildNode(SCNNode container, string name, string path, nfloat scale)
        {
            // Load the scene from the specified file
            var scene = SCNScene.FromFile(path);

            // Retrieve the root node
            var node = scene.RootNode;

            // Search for the node named "name"
            if (name.Length > 0)
            {
                node = node.FindChildNode(name, true);
            }
            else
            {
                node = node.ChildNodes [0];                 // Take the first child if no name is passed
            }
            if (scale != 0)
            {
                // Rescale based on the current bounding box and the desired scale
                // Align the node to 0 on the Y axis
                var min = new SCNVector3();
                var max = new SCNVector3();
                node.GetBoundingBox(ref min, ref max);

                var mid = SCNVector3.Add(min, max);
                mid   = SCNVector3.Multiply(mid, 0.5f);
                mid.Y = min.Y;                 // Align on bottom

                var size    = SCNVector3.Subtract(max, min);
                var maxSize = (nfloat)Math.Max(Math.Max(size.X, size.Y), size.Z);

                scale = scale / maxSize;
                mid   = SCNVector3.Multiply(mid, scale);
                mid   = -mid;

                node.Scale    = new SCNVector3(scale, scale, scale);
                node.Position = new SCNVector3(mid);
            }

            // Add to the container passed in argument
            container.AddChildNode(node);

            return(node);
        }
        private void Explosion(SCNVector3 center, List <SCNNode> nodes)
        {
            foreach (var node in nodes)
            {
                var position = node.PresentationNode.Position;
                var dir      = SCNVector3.Subtract(position, center);

                var force    = (nfloat)25.0f;
                var distance = dir.Length;

                dir = SCNVector3.Multiply(dir, force / NMath.Max(0.01f, distance));

                node.PhysicsBody.ApplyForce(dir, new SCNVector3(RandFloat(-0.2, 0.2), RandFloat(-0.2, 0.2), RandFloat(-0.2, 0.2)), true);

                node.RunAction(SCNAction.Sequence(new SCNAction[] {
                    SCNAction.Wait(2),
                    SCNAction.FadeOut(0.5f),
                    SCNAction.RemoveFromParentNode()
                }));
            }
        }
        private void UpdateEnvironmentProbe(double time)
        {
            // Update the probe only if the object has been moved or scaled,
            // only when manually placed, not too often.
            if (this.virtualObject != null &&
                this.currentTexturingMode == AREnvironmentTexturing.Manual &&
                time - this.lastProbeAnchorUpdateTime >= 1d &&
                this.requiresProbeRefresh)
            {
                // Remove existing probe anchor, if any.
                var probeAnchor = this.environmentProbeAnchor;
                if (probeAnchor != null)
                {
                    this.sceneView.Session.RemoveAnchor(probeAnchor);
                    this.environmentProbeAnchor.Dispose();
                    this.environmentProbeAnchor = null;
                }

                // Make sure the probe encompasses the object and provides some surrounding area to appear in reflections.
                var extent = SCNVector3.Multiply(this.virtualObject.GetExtents(), this.virtualObject.Scale);
                extent.X *= 3; // Reflect an area 3x the width of the object.
                extent.Z *= 3; // Reflect an area 3x the depth of the object.

                // Also include some vertical area around the object, but keep the bottom of the probe at the
                // bottom of the object so that it captures the real-world surface underneath.
                var verticalOffset = new SCNVector3(0, extent.Y, 0);
                var transform      = NMatrix4Extensions.CreateTranslation(this.virtualObject.Position + verticalOffset);
                extent.Y *= 2;

                // Create the new environment probe anchor and add it to the session.
                probeAnchor = new AREnvironmentProbeAnchor(transform, new OpenTK.NVector3(extent.X, extent.Y, extent.Z));
                this.sceneView.Session.AddAnchor(probeAnchor);

                // Remember state to prevent updating the environment probe too often.
                this.environmentProbeAnchor    = probeAnchor;
                this.lastProbeAnchorUpdateTime = CoreAnimation.CAAnimation.CurrentMediaTime();
                this.requiresProbeRefresh      = false;
            }
        }
        void CharacterNodeHitWallWithContact(SCNNode capsule, SCNPhysicsContact contact)
        {
            if (capsule.ParentNode != Character.Node)
            {
                return;
            }

            if (maxPenetrationDistance > contact.PenetrationDistance)
            {
                return;
            }

            maxPenetrationDistance = contact.PenetrationDistance;

            var        charPosition = Character.Node.Position;
            SCNVector3 n            = contact.ContactNormal;

            SCNVector3.Multiply(ref n, (float)contact.PenetrationDistance, out n);
            n.Y = 0;

            SCNVector3.Add(ref charPosition, ref n, out replacementPosition);
            positionNeedsAdjustment = true;
        }
 public static SCNVector3 Mix(SCNVector3 x, SCNVector3 y, SCNVector3 t)
 {
     return(x + SCNVector3.Multiply(t, y - x));
 }