bool ComponentBrainKamikaze::canDetectPlayer(const Actor &player) { ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(player.getComponent("Physics")); if(!component) return false; vec3 playerPosition3D = component->getPosition(); vec2 playerPosition = vec2(playerPosition3D.x, playerPosition3D.y); vec3 ourPosition3D = getPosition3D(); vec2 ourPosition = getPosition2D(); float distance = getDistance(playerPosition, ourPosition); if(distance < maxSightDistance) { // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); } return false; }
void ComponentHealth::handleMessageExplosionOccurs(Message &message) { int baseDamage = message.getField<int>("baseDamage"); if(baseDamage <= 0) return; vec3 pos = message.getField<vec3>("position"); float distance = vec3(lastReportedPosition - pos).getMagnitude(); float p = powf((float)M_E, -SQR(distance/1.5f)); int damage = (int)(baseDamage * p); OBJECT_ID actor = message.getField<OBJECT_ID>("actor"); if(damage <= 0) return; #if 1 MessageCharacterReceivesDamage m(damage); getParentBlackBoard().relayMessage(m); #else // Do a fine-detail check against physics geometry (e.g. walls) if(rayCast(actor, lastReportedPosition, pos - lastReportedPosition, distance)) { MessageCharacterReceivesDamage m(damage); getParentBlackBoard().relayMessage(m); } #endif }
bool DT_Complex::ray_cast(const MT_Point3& source, const MT_Point3& target, MT_Scalar& lambda, MT_Vector3& normal) const { DT_RootData<const DT_Convex *> rd(m_nodes, m_leaves); return rayCast(DT_BBoxTree(m_cbox, 0, m_type), rd, source, target, lambda, normal); }
void getBestPitchToEdgeOfGrid(UDWORD x, UDWORD y, uint16_t direction, uint16_t *pitch) { HeightCallbackHelp_t help = {map_Height(x,y), 0}; rayCast(Vector3i(x, y, 0), direction, 5430, getTileHeightCallback, &help); // FIXME Magic value *pitch = help.pitch; }
void getBestPitchToEdgeOfGrid(UDWORD x, UDWORD y, uint16_t direction, uint16_t *pitch) { HeightCallbackHelp_t help = {map_Height(x, y), 0}; Vector3i src(x, y, 0); Vector3i delta(iSinCosR(direction, 5430), 0); rayCast(src.xy, (src + delta).xy, getTileHeightCallback, &help); // FIXME Magic value *pitch = help.pitch; }
bool ComponentBrainShooter::canDetectPlayer(const Actor &player) { ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(player.getComponent("Physics")); if(!component) return false; vec3 playerPosition3D = component->getPosition(); vec2 playerPosition = vec2(playerPosition3D.x, playerPosition3D.y); vec3 ourPosition3D = getPosition3D(); vec2 ourPosition = getPosition2D(); float distance = getDistance(playerPosition, ourPosition); if(distance < maxSightDistance) { float radian_fov = fov * float(M_PI / 180.0); float facingAngle = getAngleFromDirection(getCurrentFacing()); float minFOV = angle_clamp(facingAngle - radian_fov); float maxFOV = angle_clamp(facingAngle + radian_fov); float angleToTarget = getAngle(playerPosition, ourPosition); #if 0 if(isAngleWithinFOV(angleToTarget, minFOV, maxFOV)) { // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); } #else // Do a fine-detail check against physics geometry (e.g. walls) return rayCast(player, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance); #endif } return false; }
void mouse(int btn, int state, int x, int y) { //ray cast is pressed if(btn == GLUT_LEFT_BUTTON) { rayCast(x, y); } glFlush(); glutSwapBuffers(); }
BOOL fpathTileLOS(DROID *psDroid, Vector3i dest) { Vector2i dir = removeZ(dest - psDroid->pos); // Initialise the callback variables obstruction = false; rayCast(psDroid->pos, iAtan2(dir), iHypot(dir), fpathVisCallback, psDroid); return !obstruction; }
std::vector<float> Laser::scan(double x, double y, double theta) { double current_angle = theta; updateAngle(current_angle, min_angle_); for (unsigned int r = 0; r < ranges_.size(); r++) { ranges_[r] = rayCast(x, y, current_angle); updateAngle(current_angle, resolution_angle_); } return ranges_; }
void display (void) { int i; int j; clearFramebuffer (); for (i = 0;i < ImageH; i++) { for (j = 0; j < ImageW; j++) { rayCast (i, j); } } drawit (); }
Action ComponentBrainShooter::getNextAction_chase(float milliseconds) { if(!targetPlayer || isDead(targetPlayer) || (!canDetectPlayer(*targetPlayer) && getTimeInState()>resumeWanderThreshold)) { nextState = StateWander; } ComponentPhysics* component = dynamic_cast<ComponentPhysics*>(targetPlayer->getComponent("Physics")); if(!component) return Stand; vec3 playerPosition3D = component->getPosition(); vec3 ourPosition3D = getPosition3D(); vec2 playerPosition = playerPosition3D.xy(); vec2 ourPosition = ourPosition3D.xy(); float angle = getAngle(playerPosition, ourPosition); Direction desiredDirection = getDirectionFromAngle(angle); Direction currentFacing = getCurrentFacing(); if(currentFacing == desiredDirection && getDistance(playerPosition, ourPosition) < shootDistance && rayCast(*targetPlayer, ourPosition3D, playerPosition3D - ourPosition3D, maxSightDistance)) { getParentBlackBoard().relayMessage(MessagePerformAction(Stand)); return AttackOnce; } else { Action action = getActionFromAngle(angle); return action; } }
static void onMouseDown(GLFWwindow* window, int button, int action, int mods) { // AntTweakBar event if (TwEventMouseButtonGLFW(button, action)) return; // Scroll wheel press if (button == GLFW_MOUSE_BUTTON_1){ if (action == GLFW_PRESS){ s_camera.setMode(glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS ? CameraMode::ARC : CameraMode::PAN); } else if (action == GLFW_RELEASE){ s_camera.setMode(CameraMode::NONE); } } // Generate selection ray if (button == GLFW_MOUSE_BUTTON_2){ if (action == GLFW_PRESS){ // Get mouse pos double mouse_x, mouse_y; glfwGetCursorPos(window, &mouse_x, &mouse_y); // Calc selection ray int screenWidth, screenHeight; glfwGetWindowSize(window, &screenWidth, &screenHeight); double x = (2.0f * mouse_x) / double(screenWidth) - 1.0f; double y = 1.0f - (2.0f * mouse_y) / double(screenHeight); glm::vec4 ray_clip = glm::vec4(x, y, -1.0, 1.0); glm::vec4 ray_eye = glm::inverse(s_proj) * ray_clip; ray_eye = glm::vec4(ray_eye.x, ray_eye.y, -1.0, 0.0); glm::vec3 ray_wor = glm::normalize(glm::vec3(inverse(s_camera.getView()) * ray_eye)); // Ray cast event rayCast(ray_wor); } else if (action == GLFW_RELEASE) { delete g_drag; g_drag = NULL; } } }
// // PickActor - Chapter 22, page 760 // int PickActor(int *hWndPtrAddress) { HWND hWnd = (HWND)hWndPtrAddress; POINT ptCursor; GetCursorPos( &ptCursor ); // Convert the screen coordinates of the mouse cursor into // coordinates relative to the client window ScreenToClient( hWnd, &ptCursor ); RayCast rayCast(ptCursor); EditorLogic* pGame = (EditorLogic*)g_pApp->m_pGame; if (!pGame) { return INVALID_ACTOR_ID; } shared_ptr<EditorHumanView> pView = pGame->GetHumanView(); if (!pView) { return INVALID_ACTOR_ID; } // Cast a ray through the scene. The RayCast object contains an array of Intersection // objects. pView->GetScene()->Pick(&rayCast); rayCast.Sort(); // If there are any intersections, get information from the first intersection. if (!rayCast.m_NumIntersections) { return INVALID_ACTOR_ID; } Intersection firstIntersection = rayCast.m_IntersectionArray[0]; return firstIntersection.m_actorId; }
void RaycastCar::updateVehicle( btScalar step ) { m_currentVehicleSpeedKmHour = btScalar(3.6f) * getRigidBody()->getLinearVelocity().length(); const btTransform & chassisTrans = getChassisWorldTransform(); btVector3 forwardW(chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.0f)) m_currentVehicleSpeedKmHour *= btScalar(-1.0f); for (int i = 0; i < getNumWheels(); i++) { updateWheelTransform(i, false); btScalar depth; depth = rayCast(m_wheelInfo[i]); } update_suspension(step); update_engine(step); update_forces(step); apply_impulses(step); }
// ---------------------------------------------------------------------------- void btKart::updateVehicle( btScalar step ) { updateAllWheelPositions(); const btTransform& chassisTrans = getChassisWorldTransform(); btVector3 forwardW(chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); // Simulate suspension // ------------------- m_num_wheels_on_ground = 0; m_visual_wheels_touch_ground = true; for (int i=0;i<m_wheelInfo.size();i++) { rayCast( i); if(m_wheelInfo[i].m_raycastInfo.m_isInContact) m_num_wheels_on_ground++; } // Test if the kart is falling so fast // that the chassis might hit the track // ------------------------------------ bool needs_cushioning_test = false; for(int i=0; i<m_wheelInfo.size(); i++) { btWheelInfo &wheel = m_wheelInfo[i]; if(!wheel.m_was_on_ground && wheel.m_raycastInfo.m_isInContact) { needs_cushioning_test = true; break; } } if(needs_cushioning_test) { const btVector3 &v = m_chassisBody->getLinearVelocity(); btVector3 down(0, 1, 0); btVector3 v_down = (v * down) * down; // Estimate what kind of downward speed can be compensated by the // suspension. Atm the parameters are set that the suspension is // actually capped at max suspension force, so the maximum // speed that can be caught by the suspension without the chassis // hitting the ground can be based on that. Note that there are // 4 suspensions, all adding together. btScalar max_compensate_speed = m_wheelInfo[0].m_maxSuspensionForce * m_chassisBody->getInvMass() * step * 4; // If the downward speed is too fast to be caught by the suspension, // slow down the falling speed by applying an appropriately impulse: if(-v_down.getY() > max_compensate_speed) { btVector3 impulse = down * (-v_down.getY() - max_compensate_speed) / m_chassisBody->getInvMass()*0.5f; //float v_old = m_chassisBody->getLinearVelocity().getY(); //float x = m_wheelInfo[0].m_raycastInfo.m_isInContact ? m_wheelInfo[0].m_raycastInfo.m_contactPointWS.getY() : -100; m_chassisBody->applyCentralImpulse(impulse); //Log::verbose("physics", "Cushioning %f from %f m/s to %f m/s wheel %f kart %f", impulse.getY(), // v_old, m_chassisBody->getLinearVelocity().getY(), x, // m_chassisBody->getWorldTransform().getOrigin().getY() // ); } } for(int i=0; i<m_wheelInfo.size(); i++) m_wheelInfo[i].m_was_on_ground = m_wheelInfo[i].m_raycastInfo.m_isInContact; // If the kart is flying, try to keep it parallel to the ground. // ------------------------------------------------------------- if(m_num_wheels_on_ground==0) { btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1); btVector3 terrain_up = m_kart->getMaterial() && m_kart->getMaterial()->hasGravity() ? m_kart->getNormal() : Vec3(0, 1, 0); // Length of axis depends on the angle - i.e. the further awat // the kart is from being upright, the larger the applied impulse // will be, resulting in fast changes when the kart is on its // side, but not overcompensating (and therefore shaking) when // the kart is not much away from being upright. btVector3 axis = kart_up.cross(terrain_up); // To avoid the kart going backwards/forwards (or rolling sideways), // set the pitch/roll to 0 before applying the 'straightening' impulse. // TODO: make this works if gravity is changed. btVector3 av = m_chassisBody->getAngularVelocity(); av.setX(0); av.setZ(0); m_chassisBody->setAngularVelocity(av); // Give a nicely balanced feeling for rebalancing the kart m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getStabilitySmoothFlyingImpulse()); } // Work around: make sure that either both wheels on one axis // are on ground, or none of them. This avoids the problem of // the kart suddenly getting additional angular velocity because // e.g. only one rear wheel is on the ground and then the kart // rotates very abruptly. for(int i=0; i<m_wheelInfo.size(); i+=2) { if( m_wheelInfo[i ].m_raycastInfo.m_isInContact != m_wheelInfo[i+1].m_raycastInfo.m_isInContact) { int wheel_air_index = i; int wheel_ground_index = i+1; if (m_wheelInfo[i].m_raycastInfo.m_isInContact) { wheel_air_index = i+1; wheel_ground_index = i; } btWheelInfo& wheel_air = m_wheelInfo[wheel_air_index]; btWheelInfo& wheel_ground = m_wheelInfo[wheel_ground_index]; wheel_air.m_raycastInfo = wheel_ground.m_raycastInfo; } } // for i=0; i<m_wheelInfo.size(); i+=2 // Apply suspension forcen (i.e. upwards force) // -------------------------------------------- updateSuspension(step); for (int i=0;i<m_wheelInfo.size();i++) { //apply suspension force btWheelInfo& wheel = m_wheelInfo[i]; btScalar suspensionForce = wheel.m_wheelsSuspensionForce; if (suspensionForce > wheel.m_maxSuspensionForce) { suspensionForce = wheel.m_maxSuspensionForce; } btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); getRigidBody()->applyImpulse(impulse, relpos); } // Update friction (i.e. forward force) // ------------------------------------ updateFriction( step); for (int i=0;i<m_wheelInfo.size();i++) { btWheelInfo& wheel = m_wheelInfo[i]; //btVector3 relpos = wheel.m_raycastInfo.m_hardPointWS // - getRigidBody()->getCenterOfMassPosition(); //btVector3 vel = getRigidBody()->getVelocityInLocalPoint(relpos); if (wheel.m_raycastInfo.m_isInContact) { const btTransform& chassisWorldTransform = getChassisWorldTransform(); btVector3 fwd ( chassisWorldTransform.getBasis()[0][m_indexForwardAxis], chassisWorldTransform.getBasis()[1][m_indexForwardAxis], chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; } } // If configured, add a force to keep karts on the track // ----------------------------------------------------- float dif = m_kart->getKartProperties()->getStabilityDownwardImpulseFactor(); if(dif!=0 && m_num_wheels_on_ground==4) { float f = -fabsf(m_kart->getSpeed()) * dif; btVector3 downwards_impulse = m_chassisBody->getWorldTransform().getBasis() * btVector3(0, f, 0); m_chassisBody->applyCentralImpulse(downwards_impulse); } // Apply additional impulse set by supertuxkart // -------------------------------------------- if(m_time_additional_impulse>0) { float dt = step > m_time_additional_impulse ? m_time_additional_impulse : step; m_chassisBody->applyCentralImpulse(m_additional_impulse*dt); m_time_additional_impulse -= dt; } // Apply additional rotation set by supertuxkart // --------------------------------------------- if(m_time_additional_rotation>0) { btTransform &t = m_chassisBody->getWorldTransform(); float dt = step > m_time_additional_rotation ? m_time_additional_rotation : step; btQuaternion add_rot(m_additional_rotation.getY()*dt, m_additional_rotation.getX()*dt, m_additional_rotation.getZ()*dt); t.setRotation(t.getRotation()*add_rot); m_chassisBody->setWorldTransform(t); // Also apply the rotation to the interpolated world transform. // This is important (at least if the rotation is only applied // in one frame) since STK will actually use the interpolated // transform, which would otherwise only be updated one frame // later, resulting in a one-frame incorrect rotation of the // kart, or a strongly 'visual jolt' of the kart btTransform &iwt=m_chassisBody->getInterpolationWorldTransform(); iwt.setRotation(iwt.getRotation()*add_rot); m_time_additional_rotation -= dt; } } // updateVehicle
// ---------------------------------------------------------------------------- void btKart::updateVehicle( btScalar step ) { for (int i=0;i<getNumWheels();i++) { updateWheelTransform(i,false); } const btTransform& chassisTrans = getChassisWorldTransform(); btVector3 forwardW(chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); // Simulate suspension // ------------------- m_num_wheels_on_ground = 0; m_visual_wheels_touch_ground = true; for (int i=0;i<m_wheelInfo.size();i++) { btScalar depth; depth = rayCast( i); if(m_wheelInfo[i].m_raycastInfo.m_isInContact) m_num_wheels_on_ground++; } // If the kart is flying, try to keep it parallel to the ground. if(m_num_wheels_on_ground==0) { btVector3 kart_up = getChassisWorldTransform().getBasis().getColumn(1); btVector3 terrain_up(0,1,0); btVector3 axis = kart_up.cross(terrain_up); // Give a nicely balanced feeling for rebalancing the kart m_chassisBody->applyTorqueImpulse(axis * m_kart->getKartProperties()->getSmoothFlyingImpulse()); } // Work around: make sure that either both wheels on one axis // are on ground, or none of them. This avoids the problem of // the kart suddenly getting additional angular velocity because // e.g. only one rear wheel is on the ground. for(int i=0; i<m_wheelInfo.size(); i+=2) { if( m_wheelInfo[i ].m_raycastInfo.m_isInContact != m_wheelInfo[i+1].m_raycastInfo.m_isInContact) { int wheel_air_index = i; int wheel_ground_index = i+1; if (m_wheelInfo[i].m_raycastInfo.m_isInContact) { wheel_air_index = i+1; wheel_ground_index = i; } btWheelInfo& wheel_air = m_wheelInfo[wheel_air_index]; btWheelInfo& wheel_ground = m_wheelInfo[wheel_ground_index]; wheel_air.m_raycastInfo = wheel_ground.m_raycastInfo; } } // for i=0; i<m_wheelInfo.size(); i+=2 updateSuspension(step); for (int i=0;i<m_wheelInfo.size();i++) { //apply suspension force btWheelInfo& wheel = m_wheelInfo[i]; btScalar suspensionForce = wheel.m_wheelsSuspensionForce; if (suspensionForce > wheel.m_maxSuspensionForce) { suspensionForce = wheel.m_maxSuspensionForce; } btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); getRigidBody()->applyImpulse(impulse, relpos); } updateFriction( step); for (int i=0;i<m_wheelInfo.size();i++) { btWheelInfo& wheel = m_wheelInfo[i]; btVector3 relpos = wheel.m_raycastInfo.m_hardPointWS - getRigidBody()->getCenterOfMassPosition(); btVector3 vel = getRigidBody()->getVelocityInLocalPoint(relpos); if (wheel.m_raycastInfo.m_isInContact) { const btTransform& chassisWorldTransform = getChassisWorldTransform(); btVector3 fwd ( chassisWorldTransform.getBasis()[0][m_indexForwardAxis], chassisWorldTransform.getBasis()[1][m_indexForwardAxis], chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; btScalar proj2 = fwd.dot(vel); wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); wheel.m_rotation += wheel.m_deltaRotation; } else { wheel.m_rotation += wheel.m_deltaRotation; } //damping of rotation when not in contact wheel.m_deltaRotation *= btScalar(0.99); } float f = -m_kart->getSpeed() * m_kart->getKartProperties()->getDownwardImpulseFactor(); btVector3 downwards_impulse = m_chassisBody->getWorldTransform().getBasis() * btVector3(0, f, 0); m_chassisBody->applyCentralImpulse(downwards_impulse); if(m_time_additional_impulse>0) { float dt = step > m_time_additional_impulse ? m_time_additional_impulse : step; m_chassisBody->applyCentralImpulse(m_additional_impulse*dt); m_time_additional_impulse -= dt; } if(m_time_additional_rotation>0) { btTransform &t = m_chassisBody->getWorldTransform(); float dt = step > m_time_additional_rotation ? m_time_additional_rotation : step; btQuaternion add_rot(m_additional_rotation.getY()*dt, m_additional_rotation.getX()*dt, m_additional_rotation.getZ()*dt); t.setRotation(t.getRotation()*add_rot); m_chassisBody->setWorldTransform(t); // Also apply the rotation to the interpolated world transform. // This is important (at least if the rotation is only applied // in one frame) since STK will actually use the interpolated // transform, which would otherwise only be updated one frame // later, resulting in a one-frame incorrect rotation of the // kart, or a strongly 'visual jolt' of the kart btTransform &iwt=m_chassisBody->getInterpolationWorldTransform(); iwt.setRotation(iwt.getRotation()*add_rot); m_time_additional_rotation -= dt; } } // updateVehicle
void btRaycastVehicle::updateVehicle( btScalar step ) { { for (int i=0; i<getNumWheels(); i++) { updateWheelTransform(i,false); } } m_currentVehicleSpeedKmHour = btScalar(3.6) * getRigidBody()->getLinearVelocity().length(); const btTransform& chassisTrans = getChassisWorldTransform(); btVector3 forwardW ( chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.)) { m_currentVehicleSpeedKmHour *= btScalar(-1.); } // // simulate suspension // int i=0; for (i=0; i<m_wheelInfo.size(); i++) { btScalar depth; depth = rayCast( m_wheelInfo[i]); } updateSuspension(step); for (i=0; i<m_wheelInfo.size(); i++) { //apply suspension force btWheelInfo& wheel = m_wheelInfo[i]; btScalar suspensionForce = wheel.m_wheelsSuspensionForce; if (suspensionForce > wheel.m_maxSuspensionForce) { suspensionForce = wheel.m_maxSuspensionForce; } btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); getRigidBody()->applyImpulse(impulse, relpos); } updateFriction( step); for (i=0; i<m_wheelInfo.size(); i++) { btWheelInfo& wheel = m_wheelInfo[i]; btVector3 relpos = wheel.m_raycastInfo.m_hardPointWS - getRigidBody()->getCenterOfMassPosition(); btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos ); if (wheel.m_raycastInfo.m_isInContact) { const btTransform& chassisWorldTransform = getChassisWorldTransform(); btVector3 fwd ( chassisWorldTransform.getBasis()[0][m_indexForwardAxis], chassisWorldTransform.getBasis()[1][m_indexForwardAxis], chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; btScalar proj2 = fwd.dot(vel); wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); wheel.m_rotation += wheel.m_deltaRotation; } else { wheel.m_rotation += wheel.m_deltaRotation; } wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact } }
bool RayTracer::rayCastAny( const Vec3f& orig, const Vec3f& dir ) const { return rayCast( orig, dir ).triangle != 0; }