void Controls_PrimaryMouseDown() { EngineContainer* cont = new EngineContainer(); btScalar dbgR = 128.0; btVector3 v = engine_camera.m_pos; btVector3 dir = engine_camera.m_viewDir; btVector3 localInertia(0, 0, 0); btCollisionShape* cshape = new btSphereShape(dbgR); cshape->setMargin(COLLISION_MARGIN_DEFAULT); //cshape = new btCapsuleShapeZ(50.0, 100.0); btTransform startTransform; startTransform.setIdentity(); btVector3 new_pos = v; startTransform.setOrigin(btVector3(new_pos[0], new_pos[1], new_pos[2])); cshape->calculateLocalInertia(12.0, localInertia); btDefaultMotionState* motionState = new btDefaultMotionState(startTransform); btRigidBody* body = new btRigidBody(12.0, motionState, cshape, localInertia); bt_engine_dynamicsWorld->addRigidBody(body); body->setLinearVelocity(btVector3(dir[0], dir[1], dir[2]) * 6000); cont->room = Room_FindPosCogerrence(new_pos, engine_camera.m_currentRoom); cont->object_type = OBJECT_BULLET_MISC; // bullet have to destroy this user pointer body->setUserPointer(cont); body->setCcdMotionThreshold(dbgR); // disable tunneling effect body->setCcdSweptSphereRadius(dbgR); }
void Cam_FollowEntity(Camera *cam, std::shared_ptr<Entity> ent, btScalar dx, btScalar dz) { btTransform cameraFrom, cameraTo; //Reset to initial cameraFrom.setIdentity(); cameraTo.setIdentity(); std::shared_ptr<BtEngineClosestConvexResultCallback> cb = ent->callbackForCamera(); btVector3 cam_pos = cam->m_pos; ///@INFO Basic camera override, completely placeholder until a system classic-like is created if(!control_states.mouse_look)//If mouse look is off { float currentAngle = cam_angles[0] * (M_PI / 180.0); //Current is the current cam angle float targetAngle = ent->m_angles[0] * (M_PI / 180.0); //Target is the target angle which is the entity's angle itself float rotSpeed = 2.0; //Speed of rotation ///@FIXME //If Lara is in a specific state we want to rotate -75 deg or +75 deg depending on camera collision if(ent->m_bf.animations.last_state == TR_STATE_LARA_REACH) { if(cam->m_targetDir == TR_CAM_TARG_BACK) { btVector3 cam_pos2 = cam_pos; cameraFrom.setOrigin(cam_pos2); cam_pos2[0] += sinf((ent->m_angles[0] - 90.0) * (M_PI / 180.0)) * control_states.cam_distance; cam_pos2[1] -= cosf((ent->m_angles[0] - 90.0) * (M_PI / 180.0)) * control_states.cam_distance; cameraTo.setOrigin(cam_pos2); //If collided we want to go right otherwise stay left if(Cam_HasHit(cb, cameraFrom, cameraTo)) { cam_pos2 = cam_pos; cameraFrom.setOrigin(cam_pos2); cam_pos2[0] += sinf((ent->m_angles[0] + 90.0) * (M_PI / 180.0)) * control_states.cam_distance; cam_pos2[1] -= cosf((ent->m_angles[0] + 90.0) * (M_PI / 180.0)) * control_states.cam_distance; cameraTo.setOrigin(cam_pos2); //If collided we want to go to back else right if(Cam_HasHit(cb, cameraFrom, cameraTo)) cam->m_targetDir = TR_CAM_TARG_BACK; else cam->m_targetDir = TR_CAM_TARG_RIGHT; } else { cam->m_targetDir = TR_CAM_TARG_LEFT; } } } else if(ent->m_bf.animations.last_state == TR_STATE_LARA_JUMP_BACK) { cam->m_targetDir = TR_CAM_TARG_FRONT; } else if(cam->m_targetDir != TR_CAM_TARG_BACK) { cam->m_targetDir = TR_CAM_TARG_BACK;//Reset to back } //If target mis-matches current we need to update the camera's angle to reach target! if(currentAngle != targetAngle) { switch(cam->m_targetDir) { case TR_CAM_TARG_BACK: targetAngle = (ent->m_angles[0]) * (M_PI / 180.0); break; case TR_CAM_TARG_FRONT: targetAngle = (ent->m_angles[0] - 180.0) * (M_PI / 180.0); break; case TR_CAM_TARG_LEFT: targetAngle = (ent->m_angles[0] - 75.0) * (M_PI / 180.0); break; case TR_CAM_TARG_RIGHT: targetAngle = (ent->m_angles[0] + 75.0) * (M_PI / 180.0); break; default: targetAngle = (ent->m_angles[0]) * (M_PI / 180.0);//Same as TR_CAM_TARG_BACK (default pos) break; } float d_angle = cam_angles[0] - targetAngle; if(d_angle > M_PI / 2.0) { d_angle -= M_PI/180.0; } if(d_angle < -M_PI / 2.0) { d_angle += M_PI/180.0; } cam_angles[0] = fmodf(cam_angles[0] + atan2f(sinf(currentAngle - d_angle), cosf(currentAngle + d_angle)) * (engine_frame_time * rotSpeed), M_PI * 2.0); //Update camera's angle } } cam_pos = ent->camPosForFollowing(dz); //Code to manage screen shaking effects if((renderer.camera()->m_shakeTime > 0.0) && (renderer.camera()->m_shakeValue > 0.0)) { cam_pos[0] += (std::fmod(rand(), std::abs(renderer.camera()->m_shakeValue)) - (renderer.camera()->m_shakeValue / 2)) * renderer.camera()->m_shakeTime;; cam_pos[1] += (std::fmod(rand(), std::abs(renderer.camera()->m_shakeValue)) - (renderer.camera()->m_shakeValue / 2)) * renderer.camera()->m_shakeTime;; cam_pos[2] += (std::fmod(rand(), std::abs(renderer.camera()->m_shakeValue)) - (renderer.camera()->m_shakeValue / 2)) * renderer.camera()->m_shakeTime;; renderer.camera()->m_shakeTime = (renderer.camera()->m_shakeTime < 0.0)?(0.0):(renderer.camera()->m_shakeTime)-engine_frame_time; } cameraFrom.setOrigin(cam_pos); cam_pos[2] += dz; cameraTo.setOrigin(cam_pos); if(Cam_HasHit(cb, cameraFrom, cameraTo)) { cam_pos.setInterpolate3(cameraFrom.getOrigin(), cameraTo.getOrigin(), cb->m_closestHitFraction); cam_pos += cb->m_hitNormalWorld * 2.0; } if (dx != 0.0) { cameraFrom.setOrigin(cam_pos); cam_pos += dx * cam->m_rightDir; cameraTo.setOrigin(cam_pos); if(Cam_HasHit(cb, cameraFrom, cameraTo)) { cam_pos.setInterpolate3(cameraFrom.getOrigin(), cameraTo.getOrigin(), cb->m_closestHitFraction); cam_pos += cb->m_hitNormalWorld * 2.0; } cameraFrom.setOrigin(cam_pos); cam_pos[0] += sinf(cam_angles[0]) * control_states.cam_distance; cam_pos[1] -= cosf(cam_angles[0]) * control_states.cam_distance; cameraTo.setOrigin(cam_pos); if(Cam_HasHit(cb, cameraFrom, cameraTo)) { cam_pos.setInterpolate3(cameraFrom.getOrigin(), cameraTo.getOrigin(), cb->m_closestHitFraction); cam_pos += cb->m_hitNormalWorld * 2.0; } } //Update cam pos cam->m_pos = cam_pos; //Modify cam pos for quicksand rooms cam->m_pos[2] -= 128.0; cam->m_currentRoom = Room_FindPosCogerrence(cam->m_pos, cam->m_currentRoom); cam->m_pos[2] += 128.0; if((cam->m_currentRoom != NULL) && (cam->m_currentRoom->flags & TR_ROOM_FLAG_QUICKSAND)) { cam->m_pos[2] = cam->m_currentRoom->bb_max[2] + 2.0 * 64.0; } cam->setRotation(cam_angles); cam->m_currentRoom = Room_FindPosCogerrence(cam->m_pos, cam->m_currentRoom); }
void Game_ApplyControls(std::shared_ptr<Entity> ent) { int8_t look_logic[3]; // Keyboard move logic std::array<int8_t,3> move_logic; move_logic[0] = control_states.move_forward - control_states.move_backward; move_logic[1] = control_states.move_right - control_states.move_left; move_logic[2] = control_states.move_up - control_states.move_down; // Keyboard look logic look_logic[0] = control_states.look_left - control_states.look_right; look_logic[1] = control_states.look_down - control_states.look_up; look_logic[2] = control_states.look_roll_right - control_states.look_roll_left; // APPLY CONTROLS cam_angles[0] += 2.2 * engine_frame_time * look_logic[0]; cam_angles[1] += 2.2 * engine_frame_time * look_logic[1]; cam_angles[2] += 2.2 * engine_frame_time * look_logic[2]; if(!renderer.world()) { if(control_mapper.use_joy) { if(control_mapper.joy_look_x != 0) { cam_angles[0] -=0.015 * engine_frame_time * control_mapper.joy_look_x; } if(control_mapper.joy_look_y != 0) { cam_angles[1] -=0.015 * engine_frame_time * control_mapper.joy_look_y; } } if(control_states.mouse_look) { cam_angles[0] -= 0.015 * control_states.look_axis_x; cam_angles[1] -= 0.015 * control_states.look_axis_y; control_states.look_axis_x = 0.0; control_states.look_axis_y = 0.0; } renderer.camera()->setRotation(cam_angles); btScalar dist = (control_states.state_walk)?(control_states.free_look_speed * engine_frame_time * 0.3):(control_states.free_look_speed * engine_frame_time); renderer.camera()->moveAlong(dist * move_logic[0]); renderer.camera()->moveStrafe(dist * move_logic[1]); renderer.camera()->moveVertical(dist * move_logic[2]); return; } if(control_mapper.use_joy) { if(control_mapper.joy_look_x != 0) { cam_angles[0] -=engine_frame_time * control_mapper.joy_look_x; } if(control_mapper.joy_look_y != 0) { cam_angles[1] -=engine_frame_time * control_mapper.joy_look_y; } } if(control_states.mouse_look) { cam_angles[0] -= 0.015 * control_states.look_axis_x; cam_angles[1] -= 0.015 * control_states.look_axis_y; control_states.look_axis_x = 0.0; control_states.look_axis_y = 0.0; } if(control_states.free_look || !std::dynamic_pointer_cast<Character>(ent)) { btScalar dist = (control_states.state_walk)?(control_states.free_look_speed * engine_frame_time * 0.3):(control_states.free_look_speed * engine_frame_time); renderer.camera()->setRotation(cam_angles); renderer.camera()->moveAlong(dist * move_logic[0]); renderer.camera()->moveStrafe(dist * move_logic[1]); renderer.camera()->moveVertical(dist * move_logic[2]); renderer.camera()->m_currentRoom = Room_FindPosCogerrence(renderer.camera()->m_pos, renderer.camera()->m_currentRoom); } else if(control_states.noclip) { btVector3 pos; btScalar dist = (control_states.state_walk)?(control_states.free_look_speed * engine_frame_time * 0.3):(control_states.free_look_speed * engine_frame_time); renderer.camera()->setRotation(cam_angles); renderer.camera()->moveAlong(dist * move_logic[0]); renderer.camera()->moveStrafe(dist * move_logic[1]); renderer.camera()->moveVertical(dist * move_logic[2]); renderer.camera()->m_currentRoom = Room_FindPosCogerrence(renderer.camera()->m_pos, renderer.camera()->m_currentRoom); ent->m_angles[0] = 180.0 * cam_angles[0] / M_PI; pos = renderer.camera()->m_pos + renderer.camera()->m_viewDir * control_states.cam_distance; ent->m_transform.getOrigin() = pos; ent->updateTransform(); } else { std::shared_ptr<Character> ch = std::dynamic_pointer_cast<Character>(ent); // Apply controls to Lara ch->m_command.action = control_states.state_action; ch->m_command.ready_weapon = control_states.do_draw_weapon; ch->m_command.jump = control_states.do_jump; ch->m_command.shift = control_states.state_walk; ch->m_command.roll = ((control_states.move_forward && control_states.move_backward) || control_states.do_roll); // New commands only for TR3 and above ch->m_command.sprint = control_states.state_sprint; ch->m_command.crouch = control_states.state_crouch; if(control_states.use_small_medi) { if(ch->getItemsCount(ITEM_SMALL_MEDIPACK) > 0 && ch->changeParam(PARAM_HEALTH, 250)) { ch->removeItem(ITEM_SMALL_MEDIPACK, 1); Audio_Send(TR_AUDIO_SOUND_MEDIPACK); } control_states.use_small_medi = !control_states.use_small_medi; } if(control_states.use_big_medi) { if(ch->getItemsCount(ITEM_LARGE_MEDIPACK) > 0 && ch->changeParam(PARAM_HEALTH, LARA_PARAM_HEALTH_MAX)) { ch->removeItem(ITEM_LARGE_MEDIPACK, 1); Audio_Send(TR_AUDIO_SOUND_MEDIPACK); } control_states.use_big_medi = !control_states.use_big_medi; } if((control_mapper.use_joy == 1) && (control_mapper.joy_move_x != 0 )) { ch->m_command.rot[0] = -360.0 / M_PI * engine_frame_time * control_mapper.joy_move_x; } else { ch->m_command.rot[0] = -360.0 / M_PI * engine_frame_time * (btScalar)move_logic[1]; } if( (control_mapper.use_joy == 1) && (control_mapper.joy_move_y != 0 ) ) { ch->m_command.rot[1] = -360.0 / M_PI * engine_frame_time * control_mapper.joy_move_y; } else { ch->m_command.rot[1] = 360.0 / M_PI * engine_frame_time * (btScalar)move_logic[0]; } ch->m_command.move = move_logic; } }