public void Move(CollisionObject item, Matrix4 transform) { var worldTransform = item.WorldTransform; var from = worldTransform.ExtractTranslation( ); var to = transform.ExtractTranslation( ); var closestConvexResultCallback = new ClosestNotMeConvexResultCallback(item, from, to) { CollisionFilterGroup = ( CollisionFilterGroups )(CollisionGroup.Objects | CollisionGroup.Level) }; World.ConvexSweepTest(( ConvexShape )item.CollisionShape, worldTransform, transform, closestConvexResultCallback); if (closestConvexResultCallback.HasHit) { Vector3 linVel; Vector3 angVel; TransformUtil.CalculateVelocity(worldTransform, transform, 1.0f, out linVel, out angVel); Matrix4 T; TransformUtil.IntegrateTransform(worldTransform, linVel, angVel, closestConvexResultCallback.ClosestHitFraction, out T); item.WorldTransform = T; } else { item.WorldTransform = transform; } }
public async void OnMouseMove(object sender, SceneMouseEventArgs e) { //var state = Mouse.GetState( ); //if ( !state.IsButtonDown( MouseButton.Left ) ) return; var dynamicScene = sender as DynamicScene; if (dynamicScene == null) { return; } var collisionObject = selectedCollisionObject; var scenarioObject = collisionObject?.UserObject as ObjectBlock; if (scenarioObject == null) { return; } var mouse = new { Close = e.Camera.UnProject(new Vector2(e.ScreenCoordinates.X, e.ScreenCoordinates.Y), -1), Far = e.Camera.UnProject(new Vector2(e.ScreenCoordinates.X, e.ScreenCoordinates.Y), 1) }; var rayCullCallback = new ClosestRayResultCullFaceCallback(mouse.Close, mouse.Far, false) { CollisionFilterGroup = CollisionFilterGroups.AllFilter, CollisionFilterMask = CollisionFilterGroups.StaticFilter }; dynamicScene.CollisionManager.World.RayTest(mouse.Close, mouse.Far, rayCullCallback); var rayCallback = new ClosestNotMeRayResultCallback(collisionObject, mouse.Close, mouse.Far) { CollisionFilterGroup = CollisionFilterGroups.AllFilter, CollisionFilterMask = CollisionFilterGroups.StaticFilter }; // GLDebug.Clear(); dynamicScene.CollisionManager.World.RayTest(mouse.Close, mouse.Far, rayCallback); if (!rayCallback.HasHit) { return; } var splice = dynamicScene.Camera.Position; if (rayCullCallback.HasHit && rayCullCallback.ClosestHitFraction < rayCallback.ClosestHitFraction) { splice = rayCullCallback.HitPointWorld; } Ray positionRay = new Ray(mouse.Close, mouse.Far); Vector3 center; float radius; collisionObject.CollisionShape.GetBoundingSphere(out center, out radius); var origin = mouse.Close + (mouse.Far - mouse.Close) * (rayCallback.ClosestHitFraction - 0.01f); var surfaceNormal = rayCallback.HitSurfaceNormal; var surfaceTangent = Vector3.Cross(rayCallback.HitSurfaceTangent, rayCallback.HitNormalWorld); var surfaceBitangent = rayCallback.HitSurfaceTangent; var basisMatrix = new Matrix4(new Vector4(surfaceTangent), new Vector4(surfaceBitangent), new Vector4(rayCallback.HitSurfaceNormal), new Vector4(0, 0, 0, 1)); GLDebug.QueuePointDraw(rayCallback.HitPointWorld); var destination = rayCallback.HitPointWorld; GLDebug.QueueLineDraw(destination, destination + surfaceNormal * 1.5f); GLDebug.QueueLineDraw(destination, destination + surfaceTangent * 0.5f); GLDebug.QueueLineDraw(destination, destination + surfaceBitangent * 0.5f); var convexCallback = new ClosestNotMeConvexResultCallback(collisionObject, collisionObject.WorldTransform.ExtractTranslation( ), destination) { CollisionFilterGroup = CollisionFilterGroups.DefaultFilter | CollisionFilterGroups.StaticFilter, CollisionFilterMask = CollisionFilterGroups.StaticFilter }; var convexShape = collisionObject.CollisionShape.IsConvex ? ( ConvexShape )collisionObject.CollisionShape : null; var extractRotation = Matrix4.CreateFromQuaternion(collisionObject.WorldTransform.ExtractRotation( )); var vector3 = destination + surfaceNormal * 1.5f; var extractTranslation = Matrix4.CreateTranslation(vector3); var from = basisMatrix * extractTranslation; var to = basisMatrix * Matrix4.CreateTranslation(destination); GLDebug.QueueLineDraw(from.ExtractTranslation( ), to.ExtractTranslation( ), Color.Red.ToColorF( ).RGBA.Xyz); await Task.Run( () => dynamicScene.CollisionManager.World.ConvexSweepTest(convexShape, from, to, convexCallback)); if (convexCallback.HasHit) { Vector3 linVel; Vector3 angVel; TransformUtil.CalculateVelocity(from, to, 1.0f, out linVel, out angVel); Matrix4 T; TransformUtil.IntegrateTransform(from, linVel, angVel, convexCallback.ClosestHitFraction, out T); //.WorldTransform = basisMatrix * T; //var instanceBasis = // scenarioObject.InstanceBasisMatrices[selectedCollisionObject.UserIndex]; //scenarioObject.AssignInstanceBasisTransform(selectedCollisionObject.UserIndex, basisMatrix); //var upAxis = basisMatrix.Row2.Xyz.Normalized(); //GLDebug.QueueLineDraw(0, selectedCollisionObject.WorldTransform.ExtractTranslation(), // selectedCollisionObject.WorldTransform.ExtractTranslation() + upAxis); //var instanceRotation = scenarioObject.InstanceRotations[selectedCollisionObject.UserIndex]; //////selectedScenarioObject.SetAxisAlignedRotation( selectedCollisionObject.UserIndex, rotation ); //var R = Quaternion.FromAxisAngle(upAxis, _axisAlignedRotation); collisionObject.WorldTransform = T; //debugPoint2 = T.ExtractTranslation(); //debugPoint3 = convexCallback.HitPointWorld + convexCallback.HitNormalWorld; //// selectedCollisionObject.WorldTransform = T; ////var localMatrix = scenarioObject.collisionSpaceMatrix.Inverted() * t.Inverted() * T; //// scenarioObject.InstanceRotations[selectedCollisionObject.UserIndex] = instanceRotation; //selectedScenarioObject.SetAxisAlignedRotation(selectedCollisionObject.UserIndex, _axisAlignedRotation); //scenarioObject.InstancePositions[selectedCollisionObject.UserIndex] = (scenarioObject.collisionSpaceMatrix.Inverted() * T).ExtractTranslation(); //localMatrix.ExtractTranslation(); } }