public static bool Raycast(Vector3 source, Vector3 destination, out RaycastHitInfo info) { if (_contextWorld == null) { Log.Core.Error("raycast attempted without world context!"); throw new InvalidOperationException("Raycast attempted without world context."); } BulletVector3 Bdestination = destination.ToBullet(); BulletVector3 Bsource = source.ToBullet(); using (var cb = new ClosestRayResultCallback(ref Bsource, ref Bdestination)) { _contextWorld.RayTestRef(ref Bsource, ref Bdestination, cb); if (cb.HasHit) { info = new RaycastHitInfo(cb.HitPointWorld.ToNumerics(), Vector3.Normalize(cb.HitNormalWorld.ToNumerics()), (RigidBodyComponent)cb.CollisionObject.UserObject, (ColliderComponent)cb.CollisionObject.CollisionShape.UserObject); return(true); } else { info = new RaycastHitInfo(destination, new Vector3(1.0f, 0.0f, 0.0f), null); return(false); } } }
private void PickBody() { Vector3 rayFrom = _demo.Freelook.Eye; Vector3 rayTo = _demo.GetCameraRayTo(); DynamicsWorld world = _demo.World; using (var rayCallback = new ClosestRayResultCallback(ref rayFrom, ref rayTo)) { world.RayTestRef(ref rayFrom, ref rayTo, rayCallback); if (rayCallback.HasHit) { Vector3 pickPosition = rayCallback.HitPointWorld; var body = rayCallback.CollisionObject as RigidBody; if (body != null) { PickRigidBody(body, ref pickPosition); } else { var collider = rayCallback.CollisionObject as MultiBodyLinkCollider; if (collider != null) { PickMultiBody(collider, ref pickPosition); } } _oldPickingDist = (pickPosition - rayFrom).Length; } } }
public bool RayCast(Vector3 From, Vector3 To, out Vector3 HitPos, out Vector3 HitNormal, out RigidBody Body) { using (ClosestRayResultCallback RayResult = new ClosestRayResultCallback(ref From, ref To)) { World.RayTestRef(ref From, ref To, RayResult); if (RayResult.HasHit) { HitPos = RayResult.HitPointWorld; HitNormal = RayResult.HitNormalWorld; Body = RayResult.CollisionObject as RigidBody; return(true); } } Body = null; HitPos = HitNormal = Vector3.Zero; return(false); }
public virtual void OnHandleInput() { if (Input.KeysPressed.Count != 0) { switch (Input.KeysPressed[0]) { case Keys.Escape: case Keys.Q: Graphics.Form.Close(); return; case Keys.F3: IsDebugDrawEnabled = !IsDebugDrawEnabled; break; case Keys.F8: Input.ClearKeyCache(); GraphicsLibraryManager.ExitWithReload = true; Graphics.Form.Close(); break; case Keys.F11: Graphics.IsFullScreen = !Graphics.IsFullScreen; break; case (Keys.Control | Keys.F): const int maxSerializeBufferSize = 1024 * 1024 * 5; DefaultSerializer serializer = new DefaultSerializer(maxSerializeBufferSize); World.Serialize(serializer); byte[] dataBytes = new byte[serializer.CurrentBufferSize]; Marshal.Copy(serializer.BufferPointer, dataBytes, 0, dataBytes.Length); System.IO.FileStream file = new System.IO.FileStream("world.bullet", System.IO.FileMode.Create); file.Write(dataBytes, 0, dataBytes.Length); file.Dispose(); break; case Keys.G: //shadowsEnabled = !shadowsEnabled; break; case Keys.Space: ShootBox(Freelook.Eye, GetRayTo(Input.MousePoint, Freelook.Eye, Freelook.Target, Graphics.FieldOfView)); break; case Keys.Return: ClientResetScene(); break; } } if (Input.MousePressed != MouseButtons.None) { Vector3 rayTo = GetRayTo(Input.MousePoint, Freelook.Eye, Freelook.Target, Graphics.FieldOfView); if (Input.MousePressed == MouseButtons.Right) { if (_world != null) { Vector3 rayFrom = Freelook.Eye; ClosestRayResultCallback rayCallback = new ClosestRayResultCallback(ref rayFrom, ref rayTo); _world.RayTestRef(ref rayFrom, ref rayTo, rayCallback); if (rayCallback.HasHit) { RigidBody body = rayCallback.CollisionObject as RigidBody; if (body != null) { if (!(body.IsStaticObject || body.IsKinematicObject)) { pickedBody = body; pickedBody.ActivationState = ActivationState.DisableDeactivation; Vector3 pickPos = rayCallback.HitPointWorld; Vector3 localPivot = Vector3.TransformCoordinate(pickPos, Matrix.Invert(body.CenterOfMassTransform)); if (Input.KeysDown.Contains(Keys.ShiftKey)) { Generic6DofConstraint dof6 = new Generic6DofConstraint(body, Matrix.Translation(localPivot), false) { LinearLowerLimit = Vector3.Zero, LinearUpperLimit = Vector3.Zero, AngularLowerLimit = Vector3.Zero, AngularUpperLimit = Vector3.Zero }; _world.AddConstraint(dof6); pickConstraint = dof6; dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 0); dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 1); dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 2); dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 3); dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 4); dof6.SetParam(ConstraintParam.StopCfm, 0.8f, 5); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 0); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 1); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 2); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 3); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 4); dof6.SetParam(ConstraintParam.StopErp, 0.1f, 5); } else { Point2PointConstraint p2p = new Point2PointConstraint(body, localPivot); _world.AddConstraint(p2p); pickConstraint = p2p; p2p.Setting.ImpulseClamp = 30; //very weak constraint for picking p2p.Setting.Tau = 0.001f; /* * p2p.SetParam(ConstraintParams.Cfm, 0.8f, 0); * p2p.SetParam(ConstraintParams.Cfm, 0.8f, 1); * p2p.SetParam(ConstraintParams.Cfm, 0.8f, 2); * p2p.SetParam(ConstraintParams.Erp, 0.1f, 0); * p2p.SetParam(ConstraintParams.Erp, 0.1f, 1); * p2p.SetParam(ConstraintParams.Erp, 0.1f, 2); */ } oldPickingDist = (pickPos - rayFrom).Length; } } } rayCallback.Dispose(); } } } else if (Input.MouseReleased == MouseButtons.Right) { RemovePickingConstraint(); } // Mouse movement if (Input.MouseDown == MouseButtons.Right) { if (pickConstraint != null) { Vector3 newRayTo = GetRayTo(Input.MousePoint, Freelook.Eye, Freelook.Target, Graphics.FieldOfView); if (pickConstraint.ConstraintType == TypedConstraintType.D6) { Generic6DofConstraint pickCon = pickConstraint as Generic6DofConstraint; //keep it at the same picking distance Vector3 rayFrom = Freelook.Eye; Vector3 dir = newRayTo - rayFrom; dir.Normalize(); dir *= oldPickingDist; Vector3 newPivotB = rayFrom + dir; Matrix tempFrameOffsetA = pickCon.FrameOffsetA; tempFrameOffsetA.M41 = newPivotB.X; tempFrameOffsetA.M42 = newPivotB.Y; tempFrameOffsetA.M43 = newPivotB.Z; pickCon.SetFrames(tempFrameOffsetA, pickCon.FrameOffsetB); } else { Point2PointConstraint pickCon = pickConstraint as Point2PointConstraint; //keep it at the same picking distance Vector3 rayFrom = Freelook.Eye; Vector3 dir = newRayTo - rayFrom; dir.Normalize(); dir *= oldPickingDist; pickCon.PivotInB = rayFrom + dir; } } } }