public virtual Object CastRay(ref IndexedVector3 from,ref IndexedVector3 to, ref VehicleRaycasterResult result) { // RayResultCallback& resultCallback; ClosestRayResultCallback rayCallback = new ClosestRayResultCallback(ref from,ref to); m_dynamicsWorld.RayTest(ref from, ref to, rayCallback); if (rayCallback.HasHit()) { RigidBody body = RigidBody.Upcast(rayCallback.m_collisionObject); if (body != null && body.HasContactResponse()) { result.m_hitPointInWorld = rayCallback.m_hitPointWorld; result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; result.m_hitNormalInWorld.Normalize(); result.m_distFraction = rayCallback.m_closestHitFraction; return body; } } else { int ibreak = 0; ClosestRayResultCallback rayCallback2 = new ClosestRayResultCallback(ref from, ref to); m_dynamicsWorld.RayTest(ref from, ref to, rayCallback2); } rayCallback.Cleanup(); return null; }
//---------------------------------------------------------------------------------------------- public virtual void MouseFunc(ref MouseState oldMouseState, ref MouseState newMouseState) { IndexedVector3 rayTo = GetRayTo(newMouseState.X, newMouseState.Y); if (WasReleased(ref oldMouseState,ref newMouseState,2)) { ShootBox(rayTo); } else if (WasReleased(ref oldMouseState,ref newMouseState,1)) { //apply an impulse if (m_dynamicsWorld != null) { ClosestRayResultCallback rayCallback = new ClosestRayResultCallback(new IndexedVector3(m_cameraPosition), rayTo); IndexedVector3 ivPos = new IndexedVector3(m_cameraPosition); IndexedVector3 ivTo = new IndexedVector3(rayTo); m_dynamicsWorld.RayTest(ref ivPos,ref ivTo, rayCallback); if (rayCallback.HasHit()) { RigidBody body = RigidBody.Upcast(rayCallback.m_collisionObject); if (body != null) { body.SetActivationState(ActivationState.ACTIVE_TAG); IndexedVector3 impulse = rayTo; impulse.Normalize(); float impulseStrength = 10f; impulse *= impulseStrength; IndexedVector3 relPos = rayCallback.m_hitPointWorld - body.GetCenterOfMassPosition(); body.ApplyImpulse(ref impulse, ref relPos); } } } } else if (newMouseState.LeftButton == ButtonState.Pressed) { //add a point to point constraint for picking if (m_dynamicsWorld != null) { IndexedVector3 rayFrom; if (m_ortho) { rayFrom = rayTo; rayFrom.Z = -100.0f; } else { rayFrom = new IndexedVector3(m_cameraPosition); } ClosestRayResultCallback rayCallback = new ClosestRayResultCallback(ref rayFrom, ref rayTo); IndexedVector3 ivPos = new IndexedVector3(m_cameraPosition); IndexedVector3 ivTo = new IndexedVector3(rayTo); m_dynamicsWorld.RayTest(ref ivPos, ref ivTo, rayCallback); if (rayCallback.HasHit()) { RigidBody body = RigidBody.Upcast(rayCallback.m_collisionObject); if (body != null) { //other exclusions? if (!(body.IsStaticObject() || body.IsKinematicObject())) { pickedBody = body; pickedBody.SetActivationState(ActivationState.DISABLE_DEACTIVATION); IndexedVector3 pickPos = rayCallback.m_hitPointWorld; IndexedVector3 localPivot = body.GetCenterOfMassTransform().Inverse() * pickPos; if (use6Dof) { IndexedMatrix tr = IndexedMatrix.Identity; tr._origin = localPivot; Generic6DofConstraint dof6 = new Generic6DofConstraint(body, ref tr, false); dof6.SetLinearLowerLimit(new IndexedVector3(0, 0, 0)); dof6.SetLinearUpperLimit(new IndexedVector3(0, 0, 0)); dof6.SetAngularLowerLimit(new IndexedVector3(0, 0, 0)); dof6.SetAngularUpperLimit(new IndexedVector3(0, 0, 0)); m_dynamicsWorld.AddConstraint(dof6); m_pickConstraint = dof6; dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 0); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 1); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 2); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 3); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 4); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_CFM, 0.8f, 5); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 0); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 1); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 2); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 3); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 4); dof6.SetParam(ConstraintParams.BT_CONSTRAINT_STOP_ERP, 0.1f, 5); } else { Point2PointConstraint p2p = new Point2PointConstraint(body, ref localPivot); m_dynamicsWorld.AddConstraint(p2p, false); p2p.m_setting.m_impulseClamp = mousePickClamping; p2p.m_setting.m_tau = 0.001f; if (m_pickConstraint != null) { int ibreak = 0; } m_pickConstraint = p2p; } //save mouse position for dragging gOldPickingPos = rayTo; gHitPos = pickPos; gOldPickingDist = (pickPos - rayFrom).Length(); //very weak constraint for picking } } } } } else if (WasReleased(ref oldMouseState,ref newMouseState,0)) { if (m_pickConstraint != null && m_dynamicsWorld != null) { m_dynamicsWorld.RemoveConstraint(m_pickConstraint); m_pickConstraint = null; //printf("removed constraint %i",gPickingConstraintId); m_pickConstraint = null; pickedBody.ForceActivationState(ActivationState.ACTIVE_TAG); pickedBody.SetDeactivationTime(0f); pickedBody = null; } } }
public void cast (CollisionWorld cw) { #if USE_BT_CLOCK frame_timer.reset (); #endif //USE_BT_CLOCK #if BATCH_RAYCASTER if (gBatchRaycaster == null) { return; } gBatchRaycaster.clearRays (); for (int i = 0; i < NUMRAYS_IN_BAR; i++) { gBatchRaycaster.addRay (source[i], dest[i]); } gBatchRaycaster.performBatchRaycast (); for (int i = 0; i < gBatchRaycaster.getNumRays (); i++) { const SpuRaycastTaskWorkUnitOut& outResult = (*gBatchRaycaster)[i]; hit[i].setInterpolate3(source[i],dest[i],outResult.hitFraction); normal[i] = outResult.hitNormal; normal[i] = normal[i].Normalize(); } #else for (int i = 0; i < NUMRAYS_IN_BAR; i++) { ClosestRayResultCallback cb = new ClosestRayResultCallback(source[i], dest[i]); cw.RayTest (ref source[i], ref dest[i], cb); if (cb.HasHit ()) { hit[i] = cb.m_hitPointWorld; normal[i] = cb.m_hitNormalWorld; normal[i] = IndexedVector3.Normalize(normal[i]); } else { hit[i] = dest[i]; normal[i] = new IndexedVector3(1.0f, 0.0f, 0.0f); } } #if USE_BT_CLOCK ms += frame_timer.getTimeMilliseconds (); #endif //USE_BT_CLOCK frame_counter++; if (frame_counter > 50) { min_ms = ms < min_ms ? ms : min_ms; max_ms = ms > max_ms ? ms : max_ms; sum_ms += ms; sum_ms_samples++; float mean_ms = (float)sum_ms/(float)sum_ms_samples; //printf("%d rays in %d ms %d %d %f\n", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms); ms = 0; frame_counter = 0; } #endif }