void BulletOpenGLApplication::Keyboard(unsigned char key, int x, int y) { // This function is called by FreeGLUT whenever // generic keys are pressed down. switch(key) { // 'z' zooms in case 'z': ZoomCamera(+CAMERA_STEP_SIZE); break; // 'x' zoom out case 'x': ZoomCamera(-CAMERA_STEP_SIZE); break; case 'w': // toggle wireframe debug drawing m_pDebugDrawer->ToggleDebugFlag(btIDebugDraw::DBG_DrawWireframe); break; case 'b': // toggle AABB debug drawing m_pDebugDrawer->ToggleDebugFlag(btIDebugDraw::DBG_DrawAabb); break; case 'd': { // create a temp object to store the raycast result RayResult result; // perform the raycast if (!Raycast(m_cameraPosition, GetPickingRay(x, y), result)) return; // return if the test failed // destroy the corresponding game object DestroyGameObject(result.pBody); break; } } }
void BulletOpenGLApplication::CreatePickingConstraint(int x, int y) { if (!m_pWorld) return; // perform a raycast and return if it fails RayResult output; if (!Raycast(m_cameraPosition, GetPickingRay(x, y), output)) return; // store the body for future reference m_pPickedBody = output.pBody; // prevent the picked object from falling asleep m_pPickedBody->setActivationState(DISABLE_DEACTIVATION); // get the hit position relative to the body we hit btVector3 localPivot = m_pPickedBody->getCenterOfMassTransform().inverse() * output.hitPoint; // create a transform for the pivot point btTransform pivot; pivot.setIdentity(); pivot.setOrigin(localPivot); // create our constraint object btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*m_pPickedBody, pivot, true); bool bLimitAngularMotion = true; if (bLimitAngularMotion) { dof6->setAngularLowerLimit(btVector3(0,0,0)); dof6->setAngularUpperLimit(btVector3(0,0,0)); } // add the constraint to the world m_pWorld->addConstraint(dof6,true); // store a pointer to our constraint m_pPickConstraint = dof6; // define the 'strength' of our constraint (each axis) float cfm = 0.5f; dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,0); dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,1); dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,2); dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,3); dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,4); dof6->setParam(BT_CONSTRAINT_STOP_CFM,cfm,5); // define the 'error reduction' of our constraint (each axis) float erp = 0.5f; dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,0); dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,1); dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,2); dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,3); dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,4); dof6->setParam(BT_CONSTRAINT_STOP_ERP,erp,5); // save this data for future reference m_oldPickingDist = (output.hitPoint - m_cameraPosition).length(); }
void StdMaterial::scatterLight( std::vector<Raycast>& raycasts, const Raycast& ray) const { double scatt = scattering(ray.origin); glm::dvec4 scatterSample(color::white, 1.0); glm::dvec3 scatterPoint = ray.origin + ray.direction * ray.limit; if(scatt <= 0.0) { const glm::dvec3& direction = ray.direction; raycasts.push_back(Raycast( Raycast::FULLY_SPECULAR, scatterSample, scatterPoint, direction)); } else if(scatt >= 1.0) { glm::dvec3 direction = _sphereRand.gen(1.0); raycasts.push_back(Raycast( Raycast::FULLY_DIFFUSE, scatterSample, scatterPoint, direction)); } else { glm::dvec3 direction = _sphereRand.gen(1.0); direction = glm::mix(ray.direction, direction, scatt); direction = glm::normalize(direction); raycasts.push_back(Raycast( Raycast::getEntropy(scatt), scatterSample, scatterPoint, direction)); } }
void TopdownCar::step() { m_car->update(m_controlState); //normalized m_sensorData.data[IS_VELOCITY]= m_car->getBody()->GetLinearVelocity().Length()/m_car->getMaxFrontSpeed(); SGenTrackNode& sector = TRACK->getSectorPoint(m_currentRaceSectorIdx); //normalized static float maxDistance = TRACK->getDistanceToFinishLine(0); m_sensorData.data[IS_LEFTDISTANCE] = TRACK->getDistanceToFinishLine(m_currentRaceSectorIdx)/ maxDistance; m_fitnessData.data[FT_DISTANCELEFT] = maxDistance - TRACK->getDistanceToFinishLine(m_currentRaceSectorIdx) + m_currentLap * maxDistance; b2Vec2 trackdirection = sector.direction; b2Vec2 cardirection = m_car->getDirection(); //normalized? m_sensorData.data[IS_TRACKANGLE] = (cardirection.x * trackdirection.x + cardirection.y * trackdirection.y + 1.0f)/2.0f; m_sensorData.data[IS_CARDISTANCETOCENTERLINE] = TRACK->getSectorDistanceToCenterline(m_currentRaceSectorIdx + 2, m_car->getBody()->GetPosition()); b2RayCastInput input; float rayLength = 100; //long enough to hit the walls b2Vec2 front = m_car->getDirection(); b2Vec2 pos = m_car->getBody()->GetPosition(); b2Vec2 right, left,hright,hleft; RotateVector(front, glm::radians(90.0f), right); RotateVector(front, glm::radians(-90.0f), left); RotateVector(front, glm::radians(45.0f), hright); RotateVector(front, glm::radians(-45.0f), hleft); m_sensorData.data[IS_RAYCAST90] = Raycast(pos,right, rayLength); m_sensorData.data[IS_RAYCAST45] = Raycast(pos,hright, rayLength); m_sensorData.data[IS_RAYCAST0] = Raycast(pos,front, rayLength); m_sensorData.data[IS_RAYCASTM45] = Raycast(pos,hleft, rayLength); m_sensorData.data[IS_RAYCASTM90] = Raycast(pos,left, rayLength); }
b2Shape* b2World::RaycastOne(const b2Segment& segment, float32* lambda, b2Vec2* normal, bool solidShapes, void* userData) { int32 maxCount = 1; b2Shape* shape; int32 count = Raycast(segment, &shape, maxCount, solidShapes, userData); if(count==0) return NULL; b2Assert(count==1); //Redundantly do TestSegment a second time, as the previous one's results are inaccessible const b2XForm xf = shape->GetBody()->GetXForm(); shape->TestSegment(xf, lambda, normal,segment,1); //We already know it returns true return shape; }
void BasicDemo::Keyboard(unsigned char key, int x, int y) { // call the base implementation first BulletOpenGLApplication::Keyboard(key, x, y); switch(key) { // Force testing case 'g': { // if 'g' is held down, apply a force m_bApplyForce = true; // prevent the box from deactivating m_pBox->GetRigidBody()->setActivationState(DISABLE_DEACTIVATION); break; } // Impulse testing case 'e': { // don't create a new explosion if one already exists // or we haven't released the key, yet if (m_pExplosion || !m_bCanExplode) break; // don't let us create another explosion until the key is released m_bCanExplode = false; // create a collision object for our explosion m_pExplosion = new btCollisionObject(); m_pExplosion->setCollisionShape(new btSphereShape(3.0f)); // get the position that we clicked RayResult result; Raycast(m_cameraPosition, GetPickingRay(x, y), result, true); // create a transform from the hit point btTransform explodeTrans; explodeTrans.setIdentity(); explodeTrans.setOrigin(result.hitPoint); m_pExplosion->setWorldTransform(explodeTrans); // set the collision flag m_pExplosion->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE); // add the explosion trigger to our world m_pWorld->addCollisionObject(m_pExplosion); break; } } }
void Player::Update(const GameContext& gameContext) { if(m_Health > 0) { auto animator = m_pModelComp->GetAnimator(); animator->SetAnimationSpeed(0.5f * m_SpeedUp); animator->SetPlayReversed(false); float deltaTime = gameContext.pGameTime->GetElapsed(); // blur effect if(m_DamageTimer > 0) { m_DamageTimer -= 0.55f * deltaTime; } Clamp<float>(m_DamageTimer, 0.2f, 0); // healing float healTime = 4.5f, healAmount = 3.25f; m_LastDamaged += deltaTime; if(m_LastDamaged >= healTime) { m_Health += healAmount * deltaTime; } Clamp<float>(m_Health,150,0); // raycasting m_ShootTimer += deltaTime; if(gameContext.pInput->IsActionTriggered(GameInput::SHOOT) && m_ShootTimer > 0.4f) { Raycast(gameContext); m_ShootTimer = 0; } // invulnerability if(m_Invulnerable) { m_InvulTimer += deltaTime; if(m_InvulTimer >= 10) { m_Invulnerable = false; m_InvulTimer = 0; } } ///// XMFLOAT2 look = XMFLOAT2(0,0); float lookSpeed = 4.f; //if(gameContext.pInput->IsMouseButtonDown(VK_LBUTTON)) //{ // auto mouseMove = gameContext.pInput->GetMouseMovement(); // //gameContext.pInput-> // look.x = static_cast<float>(mouseMove.x); // look.y = static_cast<float>(mouseMove.y); //} if(gameContext.pInput->IsKeyboardKeyDown(VK_RIGHT)) look.x = lookSpeed; if(gameContext.pInput->IsKeyboardKeyDown(VK_LEFT)) look.x = -lookSpeed; if(gameContext.pInput->IsKeyboardKeyDown(VK_UP)) look.y = lookSpeed * 0.75f; if(gameContext.pInput->IsKeyboardKeyDown(VK_DOWN)) look.y = -lookSpeed * 0.75f; if(look.x == 0 && look.y == 0) { look = gameContext.pInput->GetThumbstickPosition(false); } m_TotalYaw += look.x * m_RotationSpeed * deltaTime; m_TotalPitch += look.y * m_RotationSpeed * deltaTime; m_CamRot += look.y * m_RotationSpeed * deltaTime; GetTransform()->Rotate(0, m_TotalYaw, 0); Clamp<float>(m_CamRot, 25, -10); XMFLOAT3 camPos = m_CamObj->GetTransform()->GetPosition(); m_CamObj->GetTransform()->Translate(camPos.x, 7.5f + m_CamRot * 0.75f, camPos.z); m_CamObj->GetTransform()->Rotate(m_CamRot, 0, 0); // Reset velocity m_Velocity = XMFLOAT3(0,m_Velocity.y,0); if(m_pController->GetCollisionFlags() == PxControllerCollisionFlag::eCOLLISION_DOWN) { m_Velocity.y = 0; m_JumpVelocity = 0; } else { m_JumpVelocity -= m_JumpAcceleration * deltaTime; } XMFLOAT3 forward = GetTransform()->GetForward(); XMFLOAT3 right = GetTransform()->GetRight(); bool isMoving = false; #pragma region "input" if(gameContext.pInput->IsActionTriggered(GameInput::MOVEUP)) { isMoving = true; m_Velocity.x += forward.x * m_RunVelocity * m_SpeedUp; m_Velocity.z += forward.z * m_RunVelocity * m_SpeedUp; } if(gameContext.pInput->IsActionTriggered(GameInput::MOVEDOWN)) { isMoving = true; m_Velocity.x -= forward.x * m_RunVelocity * m_SpeedUp; m_Velocity.z -= forward.z * m_RunVelocity * m_SpeedUp; animator->SetPlayReversed(true); } float sideMove = 0.85f; if(gameContext.pInput->IsActionTriggered(GameInput::MOVERIGHT)) { isMoving = true; m_Velocity.x += right.x * m_RunVelocity * sideMove * m_SpeedUp; m_Velocity.z += right.z * m_RunVelocity * sideMove * m_SpeedUp; } if(gameContext.pInput->IsActionTriggered(GameInput::MOVELEFT)) { isMoving = true; m_Velocity.x -= right.x * m_RunVelocity * sideMove * m_SpeedUp; m_Velocity.z -= right.z * m_RunVelocity * sideMove * m_SpeedUp; } #pragma endregion if(!isMoving) { animator->Pause(); m_Velocity.x = 0.0f; m_Velocity.z = 0.0f; } else { animator->Play(); } XMFLOAT3 tempVelocity = m_Velocity; tempVelocity.y += m_JumpVelocity; XMFLOAT3 delta = tempVelocity; delta.x = tempVelocity.x * deltaTime; delta.y = tempVelocity.y * deltaTime; delta.z = tempVelocity.z * deltaTime; m_pController->Move(delta); // Speed up if(m_SpeedUp > 1) { m_SpeedUp -= 0.0715f * deltaTime; } if(m_SpeedUp < 1) { m_SpeedUp = 1; } // Add fire if(m_AddFire) { auto fire = new Fire(); AddChild(fire); fire->GetTransform()->Scale(2,2,2); m_Fires.push_back(fire); m_AddFire = false; } // Delete fires //Fire* toDel = nullptr; //for(Fire* fire : m_Fires) // if(fire) // if(fire->IsDone()) // toDel = fire; //if(toDel) //{ // for(auto it = m_Fires.begin(); it != m_Fires.end();) // { // if(toDel == *it) // { // RemoveChild(*it); // it = m_Fires.erase(it); // } // else // ++it; // } //} } }
Ray Camera::Raycast(const glm::vec2 &pt) { return Raycast(pt.x, pt.y); }
RayQueryResult GraphicsWorld::Raycast(const Ray& ray, unsigned layerMask) { return Raycast(ray, layerMask, FLOAT_INF); }
RayQueryResult GraphicsWorld::Raycast(int x, int y, unsigned layerMask) { return Raycast(x, y, layerMask, FLOAT_INF); }
RayQueryResult GraphicsWorld::Raycast(int x, int y, float maxDistance) { return Raycast(x, y, 0xffffffff, maxDistance); }
RayQueryResult GraphicsWorld::Raycast(int x, int y) { return Raycast(x, y, 0xffffffff, FLOAT_INF); }
glm::dvec4 StdCoating::indirectBrdf( std::vector<Raycast>& raycasts, const RayHitReport& report, const Raycast& incidentRay) const { // Emission glm::dvec4 emission = glm::dvec4(0.0); // Report's shorthands const glm::dvec3& pos = report.position; const glm::dvec3& tex = report.texCoord; const glm::dvec3& wallNormal = report.normal; const glm::dvec3& reflectOrig = report.reflectionOrigin; const glm::dvec3& refractOrig = report.refractionOrigin; const Material& currMaterial = *report.currMaterial; const Material& nextMaterial = *report.nextMaterial; const glm::dvec3& incident = incidentRay.direction; // StdCoating properties double rough = roughness(tex); double pRIdx = paintRefractiveIndex(tex); double entropy = Raycast::getEntropy(rough); glm::dvec4 paintFrag = paintColor(tex); glm::dvec3 pColor = glm::dvec3(paintFrag); double pOpa = paintFrag.a; // Leaved material properties double lRIdx = currMaterial.refractiveIndex(pos); // Entered material properties double eOpa = nextMaterial.opacity(pos); double eCond = nextMaterial.conductivity(pos); double eRIdx = nextMaterial.refractiveIndex(pos); glm::dvec3 eColor = nextMaterial.color(pos); // Reflection glm::dvec3 reflectNormal = getMicrofacetNormal( wallNormal, incident, rough); // Fresnel reflection double paintReflectRatio = computeReflexionRatio( lRIdx, pRIdx, incident, reflectNormal); glm::dvec4 reflectSample(0.0); glm::dvec4 diffuseSample(0.0); glm::dvec4 refractSample(0.0); // Paint if(pOpa > 0.0) { double paintReflectWeight = pOpa * paintReflectRatio; reflectSample += glm::dvec4(paintReflectWeight); double paintDiffWeight = pOpa * (1 - paintReflectRatio); diffuseSample += glm::dvec4(pColor * paintDiffWeight, paintDiffWeight); } if(pOpa < 1.0) { // Metal reflection double metalWeight = (1 - pOpa) * eCond; if(metalWeight > 0.0) { reflectSample += glm::dvec4(eColor * metalWeight, metalWeight); } if(eCond < 1.0) { // Insulator reflection double insulProb = (1 - pOpa) * (1 - eCond); double matReflectRatio = computeReflexionRatio( lRIdx, eRIdx, incident, reflectNormal); double insulReflectWeight = insulProb * matReflectRatio; reflectSample += glm::dvec4(insulReflectWeight); // Fully opaque insulator if(eOpa >= 1.0) { double matDiffWeight = insulProb * (1 - matReflectRatio); diffuseSample += glm::dvec4(eColor * matDiffWeight, matDiffWeight); } // Refraction else { double paintRefract = pOpa * (1 - paintReflectRatio); double insulRefract = insulProb * (1 - matReflectRatio); double refractWeight = paintRefract + insulRefract; glm::dvec3 refractColor = glm::mix(color::white, pColor, pOpa); refractSample += glm::dvec4(refractColor * refractWeight, refractWeight); } } } // Refraction if(refractSample.w > 0.0) { glm::dvec3 refractDir = computeRefraction( lRIdx, eRIdx, incident, reflectNormal); if(glm::dot(refractDir, wallNormal) < 0.0) { raycasts.push_back(Raycast( entropy, refractSample, refractOrig, refractDir)); } else { reflectSample += refractSample; } } // Diffuse if(diffuseSample.w > 0.0) { if(rough < 1.0) { glm::dvec3 diffuseNormal = getMicrofacetNormal( wallNormal, incident, 1.0); // Fully diffusive glm::dvec3 diffuseDir = glm::reflect( incident, diffuseNormal); raycasts.push_back(Raycast( Raycast::FULLY_DIFFUSE, diffuseSample, reflectOrig, diffuseDir)); } else { reflectSample += diffuseSample; } } // Reflection if(reflectSample.w > 0.0) { glm::dvec3 reflectDir = glm::reflect( incident, reflectNormal); raycasts.push_back(Raycast( entropy, reflectSample, reflectOrig, reflectDir)); } // No emission return emission; }