THREAD_RETURN pool_runner_thread(THREAD_ARGUMENTS parameters) { /* allocates space for the work thread task */ struct thread_pool_task_t *work_thread_task; /* retrieves the thread pool from the arguments */ struct thread_pool_t *thread_pool = (struct thread_pool_t *) parameters; /* ierates continuously */ while(TRUE) { /* locks the task condition lock */ CONDITION_LOCK(thread_pool->task_condition, thread_pool->task_condition_lock); /* iterates while the task queue is empty */ while(thread_pool->task_queue->size == 0) { /* waits for the task condition */ CONDITION_WAIT(thread_pool->task_condition, thread_pool->task_condition_lock); } /* retrieves the work thread task */ pop_value_linked_list(thread_pool->task_queue, (void **) &work_thread_task, 0); /* unlock the task condition lock */ CONDITION_UNLOCK(thread_pool->task_condition, thread_pool->task_condition_lock); /* calls the start function */ work_thread_task->start_function(NULL); } /* returns valid */ return 0; }
void RigidBodyNode::set_kinematic(bool kinematic) { CONDITION_LOCK(ph_, ph_->lock()); if (kinematic) { body_->setCollisionFlags(body_->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); body_->setActivationState(DISABLE_DEACTIVATION); } else { body_->setCollisionFlags(body_->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); body_->activate(true); } }
void RigidBodyNode::set_mass(float mass) { bool was_static(mass_ == 0.f && mass > 0.f && has_static_shapes_); mass_ = mass; CONDITION_LOCK(ph_, ph_->lock()); if (mass > 0.f && !was_static) body_->getCollisionShape()->calculateLocalInertia(mass_, inertia_); body_->setMassProps(mass_, inertia_); //Resync associated shapes if the body becomes dynamic and some of the //associated shapes do not support dynamic bodies. if (was_static) sync_shapes(true); }
void insert_task_thread_pool(struct thread_pool_t *thread_pool, struct thread_pool_task_t *thread_pool_task) { /* locks the task condition lock */ CONDITION_LOCK(thread_pool->task_condition, thread_pool->task_condition_lock); /* adds the the thread pool task to the task queue */ append_value_linked_list(thread_pool->task_queue, thread_pool_task); /* signals the task condition */ CONDITION_SIGNAL(thread_pool->task_condition); /* unlock the task condition lock */ CONDITION_UNLOCK(thread_pool->task_condition, thread_pool->task_condition_lock); }
/* virtual */ void RigidBodyNode::set_transform(const math::mat4& transform) { //TODO: It's nice to have this function block free // (along with rotate and translate functions) CONDITION_LOCK(ph_, ph_->lock()); if (body_->isKinematicObject()) { motion_state_->setWorldTransform(math::mat4_to_btTransform(transform)); } else { body_->setWorldTransform(math::mat4_to_btTransform(transform)); body_->activate(); } set_dirty(); }
/* virtual */ void RigidBodyNode::translate(float x, float y, float z) { CONDITION_LOCK(ph_, ph_->lock()); if (body_->isKinematicObject()) { btTransform t; motion_state_->getWorldTransform(t); t.setOrigin(t.getOrigin() + btVector3(x, y, z)); motion_state_->setWorldTransform(t); } else { btTransform t(body_->getWorldTransform()); t.setOrigin(t.getOrigin() + btVector3(x, y, z)); body_->setWorldTransform(t); body_->activate(); } set_dirty(); }
void RigidBodyNode::clear_forces() { CONDITION_LOCK(ph_, ph_->lock()); body_->clearForces(); }
void RigidBodyNode::apply_central_impulse(const math::vec3& impulse) { CONDITION_LOCK(ph_, ph_->lock()); body_->applyCentralImpulse(math::vec3_to_btVector3(impulse)); }
void RigidBodyNode::apply_impulse(const math::vec3& impulse, const math::vec3& rel_pos) { CONDITION_LOCK(ph_, ph_->lock()); body_->applyImpulse(math::vec3_to_btVector3(impulse), math::vec3_to_btVector3(rel_pos)); }
void RigidBodyNode::apply_torque_impulse(const math::vec3& torque) { CONDITION_LOCK(ph_, ph_->lock()); body_->applyTorqueImpulse(math::vec3_to_btVector3(torque)); }
void RigidBodyNode::apply_central_force(const math::vec3& force) { CONDITION_LOCK(ph_, ph_->lock()); body_->applyCentralForce(math::vec3_to_btVector3(force)); }
void RigidBodyNode::apply_force(const math::vec3& force, const math::vec3& rel_pos) { CONDITION_LOCK(ph_, ph_->lock()); body_->applyForce(math::vec3_to_btVector3(force), math::vec3_to_btVector3(rel_pos)); }
void RigidBodyNode::set_restitution(float rest) { CONDITION_LOCK(ph_, ph_->lock()); body_->setRestitution(rest); }
void RigidBodyNode::set_rolling_friction(float frict) { CONDITION_LOCK(ph_, ph_->lock()); body_->setRollingFriction(frict); }
void RigidBodyNode::set_linear_velocity(const math::vec3& vel) { CONDITION_LOCK(ph_, ph_->lock()); body_->setLinearVelocity(math::vec3_to_btVector3(vel)); }
void RigidBodyNode::sync_shapes(bool do_not_lock) { has_static_shapes_ = false; if (!shapes_.size()) { if (body_->getCollisionShape() != bullet_empty_shape_) { CONDITION_LOCK(ph_ && !do_not_lock, ph_->lock()); body_->setCollisionShape(bullet_empty_shape_); } } else { if (body_->isStaticObject()) { //Static rigid body shape construction if (shapes_.size() == 1 && shapes_[0].shape->is_static_shape()) { //Rigid body has only one collision shape // //TODO: Implement offset transform for static rigid bodies. // Now the transform of the collision shape is ignored. // Do not forget to fix set_mass and set_kinematic funcs. auto sh = shapes_[0].shape->construct_static(); assert(sh); CONDITION_LOCK(ph_ && !do_not_lock, ph_->lock()); body_->setCollisionShape(sh); if (!shapes_[0].shape->has_identical_shape_constructor()) has_static_shapes_ = true; } else { //Rigid body has more than one collision shape or //it cannot be static auto cs = new btCompoundShape(); for (auto sh : shapes_) { if (sh.shape->is_static_shape()) { cs->addChildShape( math::mat4_to_btTransform(sh.transform), sh.shape->construct_static()); if (!sh.shape->has_identical_shape_constructor()) has_static_shapes_ = true; } else if (sh.shape->is_dynamic_shape()) sh.shape->construct_dynamic( cs, math::mat4_to_btTransform(sh.transform)); } //If all the shapes support dynamic bodies, recalculate inertia //(in case if the body becomes dynamic) if (!has_static_shapes_) { cs->calculateLocalInertia(mass_, inertia_); body_->setMassProps(mass_, inertia_); } CONDITION_LOCK(ph_ && !do_not_lock, ph_->lock()); body_->setCollisionShape(cs); if (bullet_compound_shape_) delete bullet_compound_shape_; bullet_compound_shape_ = cs; } } else { //Dynamic rigid body shape construction auto cs = new btCompoundShape(); for (auto sh : shapes_) { if (sh.shape->is_dynamic_shape()) sh.shape->construct_dynamic( cs, math::mat4_to_btTransform(sh.transform)); } cs->calculateLocalInertia(mass_, inertia_); body_->setMassProps(mass_, inertia_); CONDITION_LOCK(ph_ && !do_not_lock, ph_->lock()); body_->setCollisionShape(cs); if (bullet_compound_shape_) delete bullet_compound_shape_; bullet_compound_shape_ = cs; } } }
void RigidBodyNode::set_damping(float lin_damping, float ang_damping) { CONDITION_LOCK(ph_, ph_->lock()); body_->setDamping(lin_damping, ang_damping); }