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