/** * We attempt to have the player pick up a gun by raycasting to whatever the player is * looking at, and then if we hit something in the raycast, we check the distance, * and then we have to determine whether or not it's a gun. */ void attempt_to_pick_up_weapon() { if (player_held_item != nullptr) return; GLfloat yaw = camera._yaw; GLfloat pitch = camera._pitch; glm::vec3 pos = camera._position; btScalar xz_len = cos(glm::radians(pitch)); btVector3 bt_to(xz_len * cos(glm::radians(yaw)), sin(glm::radians(pitch)), xz_len * sin(glm::radians(yaw))); btVector3 bt_from(pos.x, pos.y, pos.z); bt_from += bt_to; bt_to *= 20; btCollisionWorld::ClosestRayResultCallback result(bt_from, bt_to); world->get_dynamics_world()->rayTest(bt_from, bt_to, result); if (result.hasHit() && (bt_from - result.m_hitPointWorld).length() < 0.7) { btRigidBody* collided = const_cast<btRigidBody*>(static_cast<const btRigidBody*>(result.m_collisionObject)); Larp::Node* user_pointer = static_cast<Larp::Node*>(collided->getUserPointer()); Weapon* weaponptr = nullptr; if(user_pointer != nullptr) { for (auto& it:pickupable_items) { if(it->_node == user_pointer) { weaponptr = it; } } } if (weaponptr != nullptr) { world->get_dynamics_world()->removeRigidBody(const_cast<btRigidBody*>(collided)); user_pointer->detach_this_from_parent(); Larp::Node* gun_parent = camera_node->create_child(); gun_parent->attach_child(user_pointer); user_pointer->set_position(0.0, 0.0, 0.0); gun_parent->set_position(-0.2, -0.25, weaponptr->_offset_z); glm::vec3 player_scale = static_cast<Larp::Node*>(player->get_user_pointer())->get_scale(); glm::vec3 user_pointer_scale = user_pointer->get_scale(); user_pointer->set_scale(user_pointer_scale.x / player_scale.x, user_pointer_scale.y / player_scale.y, user_pointer_scale.z / player_scale.z); user_pointer->set_orientation(glm::quat(1, 0, 0, 0)); user_pointer->pitch(weaponptr->_offset_pitch); user_pointer->yaw(weaponptr->_offset_yaw); // Finally, update our player_held_item to denote that we are actually holding something player_held_item = weaponptr; } } }
float du_check_ray_hit(du_body_id du_body_a, float *from, float *to, bool local, du_body_id du_body_b_arr[], int du_body_b_num, du_body_id *du_body_b_hit_ptr) { duWorld *world = get_active_world(); btCollisionObject *bt_body_a = reinterpret_cast <btCollisionObject*>(du_body_a); btCollisionObject **bt_body_b_arr = reinterpret_cast <btCollisionObject**>(du_body_b_arr); btVector3 bt_from(from[0], from[1], from[2]); btVector3 bt_to(to[0], to[1], to[2]); btVector3 bt_from_w, bt_to_w; if (local) { // offsets in local space of A bt_from_w = bt_body_a->getWorldTransform() * bt_from; bt_to_w = bt_body_a->getWorldTransform() * bt_to; } else { // offsets in world space btTransform transform = bt_body_a->getWorldTransform(); btVector3 origin = transform.getOrigin(); bt_from_w = origin + bt_from; bt_to_w = origin + bt_to; } ClosestArrayRayResultCallback ray_cb(bt_body_b_arr, du_body_b_num); world->rayTest(bt_from_w, bt_to_w, ray_cb); if (ray_cb.hasHit()) { *du_body_b_hit_ptr = (du_body_id)ray_cb.m_collisionObject; return ray_cb.m_closestHitFraction; } else { *du_body_b_hit_ptr = NULL; return 1.0; } }