void Physics3DComponent::syncNodeToPhysics() { if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY || _physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::COLLIDER) { auto mat = _owner->getNodeToWorldTransform(); //remove scale, no scale support for physics float oneOverLen = 1.f / sqrtf(mat.m[0] * mat.m[0] + mat.m[1] * mat.m[1] + mat.m[2] * mat.m[2]); mat.m[0] *= oneOverLen; mat.m[1] *= oneOverLen; mat.m[2] *= oneOverLen; oneOverLen = 1.f / sqrtf(mat.m[4] * mat.m[4] + mat.m[5] * mat.m[5] + mat.m[6] * mat.m[6]); mat.m[4] *= oneOverLen; mat.m[5] *= oneOverLen; mat.m[6] *= oneOverLen; oneOverLen = 1.f / sqrtf(mat.m[8] * mat.m[8] + mat.m[9] * mat.m[9] + mat.m[10] * mat.m[10]); mat.m[8] *= oneOverLen; mat.m[9] *= oneOverLen; mat.m[10] *= oneOverLen; mat *= _invTransformInPhysics; if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY) { auto body = static_cast<Physics3DRigidBody*>(_physics3DObj)->getRigidBody(); auto motionState = body->getMotionState(); motionState->setWorldTransform(convertMat4TobtTransform(mat)); body->setMotionState(motionState); } else if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::COLLIDER) { auto object = static_cast<Physics3DCollider*>(_physics3DObj)->getGhostObject(); object->setWorldTransform(convertMat4TobtTransform(mat)); } } }
bool FrustumPhysicsObject::frustumInit(unsigned int attributeIndex,short collisionFilterGroup) { if(attributeIndex < 0) { return false; } attributeIndex_ = attributeIndex; collisionFilterGroup_ = collisionFilterGroup; AttributePtr<Attribute_Camera> ptr_camera = itrCamera_3.at(attributeIndex); btVector3 localInertia; localInertia.setZero(); btCollisionShape* collisionShape = CollisionShapes::Instance()->getFrustumShape(attributeIndex_); btScalar mass = static_cast<btScalar>(1); setMassProps(mass, localInertia); setCollisionShape(collisionShape); btTransform world; AttributePtr<Attribute_Spatial> ptr_spatial = itrCamera_3.at(attributeIndex_)->ptr_spatial; AttributePtr<Attribute_Position> ptr_position = ptr_spatial->ptr_position; world.setOrigin(convert(ptr_position->position)); world.setRotation(convert(ptr_spatial->rotation)); setWorldTransform(world); setCollisionFlags(getCollisionFlags() | CF_NO_CONTACT_RESPONSE); forceActivationState(DISABLE_DEACTIVATION); return true; }
PhysicsTrigger::PhysicsTrigger(Trigger *trigger) { // We use the radius of the scale for the trigger since it takes half extents. auto shape = new btBoxShape(btConvert(trigger->getScale() * 0.5f)); shape->setMargin(0.01f); // Set the physic's object transformation matrix to be the same // as the transform matrix of the game object. btTransform transform; transform.setIdentity(); transform.setOrigin(btConvert(trigger->getPosition())); transform.setRotation(btConvert(trigger->getRotation())); auto state = new btDefaultMotionState(); state->setWorldTransform(transform); mActor = new btRigidBody(0.0f, state, shape); // Set the trigger flag on the actor. // CF_NO_CONTACT_RESPONSE set's it to be a trigger interaction // CF_CUSTOM_MATERIAL_CALLBACK let's us get notifications. mActor->setCollisionFlags( mActor->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK ); // create a relationship between the trigger and the physics representation mTrigger = trigger; }
void PlayerPhysicsObject::handleInput(float delta) { std::vector<int> playerAttributes = itrPhysics_3.ownerAt(attributeIndex_)->getAttributes(ATTRIBUTE_PLAYER); if(playerAttributes.size() > 1) { ERROR_MESSAGEBOX("More than one controller for one player. Not tested.") } for(unsigned int i=0; i<playerAttributes.size(); i++) { AttributePtr<Attribute_Player> ptr_player = ptr_player = itrPlayer.at(playerAttributes.at(i)); AttributePtr<Attribute_Input> ptr_input = ptr_player->ptr_input; AttributePtr<Attribute_Health> health = ptr_player->ptr_health; if(health->health <= 0) { continue; } //-------------------------------------------------------------------------------------- //Look and move //-------------------------------------------------------------------------------------- yaw_ += ptr_input->rotation.x; btVector3 move = ptr_player->currentSpeed*btVector3(ptr_input->position.x, 0, ptr_input->position.y); //lower player speed when recently damaged if(ptr_player->timeSinceLastDamageTaken < 1.0f) { move *= 0.75f; } //Move player move = move.rotate(btVector3(0,1,0),yaw_); move = btVector3(move.x(), getLinearVelocity().y(), move.z()); setLinearVelocity(move); //Rotate player btTransform world; world = getWorldTransform(); world.setRotation(btQuaternion(yaw_,0,0)); setWorldTransform(world); //Jetpack if(ptr_player->jetpack) { float jetpackPower = -getGravity().y()*1.5f; world = getWorldTransform(); btVector3 velocity = getLinearVelocity(); if(world.getOrigin().y() < 18.0f) { setLinearVelocity(btVector3(move.x(), velocity.y()+jetpackPower*delta, move.z())); } } else if(ptr_input->jump && ptr_player->hovering) //Jump { float jumpPower = 600.0f; applyCentralImpulse(btVector3(0.0f, jumpPower, 0.0f)); //applyCentralForce(btVector3(0.0f, jumpPower, 0.0f)); } } }
void the::camera::deserialize(const pugi::xml_node &node) { _fov = node.attribute("FOV").as_float(); _zFar = node.attribute("zFar").as_float(); _zNear = node.attribute("zNear").as_float(); setWorldTransform(mat4(node)); //setLocalPosition(eyePosition); }
void PlayerPhysicsObject::hover(float delta, float hoverHeight) { float deltaHeightMaximum = 0.0f; btVector3 offset[] = {btVector3( 0.15f, 0.0f, 0.15f), btVector3( 0.15f, 0.0f, -0.15f), btVector3(-0.15f, 0.0f, 0.15f), btVector3(-0.15f, 0.0f, -0.15f) }; for(unsigned int i=0; i<4; i++) { btVector3 from = btVector3(0.0f, 0.0f, 0.0f); btVector3 to = (from - btVector3(0.0f,hoverHeight*2.0f,0.0f)) + offset[i]; from += offset[i]; from += getWorldTransform().getOrigin(); to += getWorldTransform().getOrigin(); btQuaternion btqt = getWorldTransform().getRotation(); btCollisionWorld::ClosestRayResultCallback ray(from,to); ray.m_collisionFilterGroup = XKILL_Enums::PhysicsAttributeType::RAY; ray.m_collisionFilterMask = XKILL_Enums::PhysicsAttributeType::WORLD; dynamicsWorld_->rayTest(from,to,ray); //cast ray from player position straight down if(ray.hasHit()) { btVector3 point = from.lerp(to,ray.m_closestHitFraction); float length = (point - from).length(); float deltaHeight = hoverHeight-length; if(deltaHeight > deltaHeightMaximum) { deltaHeightMaximum = deltaHeight; } } debugDrawer_->drawLine(from, to, btVector3(0.2f, 1.0f, 0.2f)); } bool isHovering = false; if(deltaHeightMaximum > 0.0f) { btTransform worldTransform; worldTransform = getWorldTransform(); worldTransform.setOrigin(worldTransform.getOrigin() + btVector3(0.0f,deltaHeightMaximum,0.0f)*delta/0.25f); setWorldTransform(worldTransform); setLinearVelocity(getLinearVelocity()+btVector3(0.0f,-getLinearVelocity().y(),0.0f)); isHovering = true; } std::vector<int> playerAttributes = itrPhysics_3.ownerAt(attributeIndex_)->getAttributes(ATTRIBUTE_PLAYER); for(unsigned int i=0; i<playerAttributes.size(); i++) { AttributePtr<Attribute_Player> ptr_player = itrPlayer.at(playerAttributes.at(i)); ptr_player->hovering = isHovering; } }
void PhysicsObject::handleOutOfBounds() { btTransform transform; btVector3 newPosition = btVector3(0.0f, 10.0f, 0.0f); transform = getWorldTransform(); transform.setOrigin(newPosition); setWorldTransform(transform); DEBUGPRINT("A physics object was out of bounds. It was moved to a new position " << newPosition.x() << " " << newPosition.y() << " " << newPosition.z()); }
void FrustumPhysicsObject::onUpdate(float delta) { btMatrix3x3 view = convert(itrCamera_3.at(attributeIndex_)->mat_view); btVector3 pos = convert(itrCamera_3.at(attributeIndex_)->ptr_spatial->ptr_position->position); btQuaternion q; view.getRotation(q); btTransform world = getWorldTransform(); world.setRotation(q); world.setOrigin(pos); setWorldTransform(world); setCollisionShape(CollisionShapes::Instance()->getFrustumShape(attributeIndex_)); }
void World:: reset() { btCollisionObjectArray a = dynamicsWorld->getCollisionObjectArray(); for (int i = 0; i < a.size(); i++) { auto o = a[i]; if (!o->isStaticOrKinematicObject()) { std::cout << "Object: " << o->getUserPointer() << std::endl; btTransform t = o->getWorldTransform(); btVector3 v = t.getOrigin(); if (v.getY() < -10) { std::shared_ptr<app::gl::AppObject> new_object; dynamicsWorld->removeCollisionObject(o); for (auto i = objects.begin(); i != objects.end(); ++i) { if (i->get() == o->getUserPointer()) { new_object = std::make_shared<app::gl::AppObject>(*(i->get())); v.setX(disx(gen)); v.setY(disy(gen)); v.setZ(disz(gen)); t.setOrigin(v); new_object->setWorldTransform(t); objects.erase(i); break; } } addToWorld(new_object, btRigidBody::btRigidBodyConstructionInfo(new_object->getMass(), nullptr, nullptr, new_object->getInitialInertia())); } else { v.setX(disx(gen)); v.setY(disy(gen)); v.setZ(disz(gen)); t.setOrigin(v); o->setWorldTransform(t); o->setInterpolationLinearVelocity(btVector3(0,0,0)); o->setInterpolationAngularVelocity(btVector3(0,0,0)); o->setActivationState(1); o->activate(true); } } } }
void WPainter::drawPie(const WRectF& rectangle, int startAngle, int spanAngle) { WTransform oldTransform = WTransform(worldTransform()); translate(rectangle.center().x(), rectangle.center().y()); scale(1., rectangle.height() / rectangle.width()); WPainterPath path(WPointF(0.0, 0.0)); path.arcTo(0.0, 0.0, rectangle.width() / 2.0, startAngle / 16., spanAngle / 16.); path.closeSubPath(); drawPath(path); setWorldTransform(oldTransform); }
void btRigidBody::internalWritebackVelocity(btScalar timeStep) { (void) timeStep; if (m_inverseMass) { setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity); setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity); //correct the position/orientation based on push/turn recovery btTransform newTransform; btTransformUtil::integrateTransform(getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform); setWorldTransform(newTransform); //m_originalBody->setCompanionId(-1); } // m_deltaLinearVelocity.setZero(); // m_deltaAngularVelocity .setZero(); // m_pushVelocity.setZero(); // m_turnVelocity.setZero(); }
void WPainter::drawChord(const WRectF& rectangle, int startAngle, int spanAngle) { WTransform oldTransform = WTransform(worldTransform()); translate(rectangle.center().x(), rectangle.center().y()); scale(1., rectangle.height() / rectangle.width()); double start = startAngle / 16.; double span = spanAngle / 16.; WPainterPath path; path.arcMoveTo(0, 0, rectangle.width()/2., start); path.arcTo(0, 0, rectangle.width()/2., start, span); path.closeSubPath(); drawPath(path); setWorldTransform(oldTransform); }
void PhysicsObject::hover(float delta, float hoverHeight) { btVector3 from = getWorldTransform().getOrigin(); btVector3 to = from - btVector3(0.0f,hoverHeight*2.0f,0.0f); btCollisionWorld::ClosestRayResultCallback ray(from,to); ray.m_collisionFilterGroup = XKILL_Enums::PhysicsAttributeType::RAY; ray.m_collisionFilterMask = XKILL_Enums::PhysicsAttributeType::WORLD; dynamicsWorld_->rayTest(from,to,ray); //cast ray from player position straight down if(ray.hasHit()) { btVector3 point = from.lerp(to,ray.m_closestHitFraction); float length = (point - from).length(); float something = hoverHeight-length; if(something > 0.0f) { btTransform worldTransform; worldTransform = getWorldTransform(); worldTransform.setOrigin(worldTransform.getOrigin() + btVector3(0.0f,something,0.0f)*delta/0.25f); setWorldTransform(worldTransform); setLinearVelocity(getLinearVelocity()+btVector3(0.0f,-getLinearVelocity().y(),0.0f)); } } }
void BulletElement::updateWorldTransform(const Matrix4d& T_link_to_world) { setWorldTransform(T_link_to_world*(this->T_elem_to_link)); }
void Element::updateWorldTransform(const Eigen::Matrix4d& T_local_to_world) { setWorldTransform(T_local_to_world*(this->T_element_to_local)); }
void SimoxMotionState::updateTransform() { //Eigen::Matrix4f m = Eigen::Matrix4f::Identity(); //m.block(0,3,3,1) = com; setWorldTransform(m_startWorldTrans); }
BulletElement::BulletElement(const Matrix4d& T_elem_to_link, Shape shape, const vector<double>& params) : T_elem_to_link(T_elem_to_link),shape(shape) { //DEBUG //std::cout << "BulletElement::BulletElement: START" << std::endl; //END_DEBUG btCollisionShape* bt_shape; switch (shape) { case BOX: //DEBUG //std::cout << "BulletElement::BulletElement: Create BOX ..." << std::endl; //END_DEBUG bt_shape = new btBoxShape( btVector3(params[0]/2,params[1]/2,params[2]/2) ); bt_shape->setMargin(0.0); //DEBUG //std::cout << "BulletElement::BulletElement: Created BOX" << std::endl; //END_DEBUG break; case SPHERE: if (true || params[0] != 0) { //DEBUG //std::cout << "BulletElement::BulletElement: Create SPHERE ..." << std::endl; //END_DEBUG bt_shape = new btSphereShape(params[0]) ; //DEBUG //std::cout << "BulletElement::BulletElement: Created SPHERE" << std::endl; //END_DEBUG } else { //DEBUG //std::cout << "BulletElement::BulletElement: THROW" << std::endl; //END_DEBUG throw zeroRadiusSphereException(); } break; case CYLINDER: //DEBUG //std::cout << "BulletElement::BulletElement: Create CYLINDER ..." << std::endl; //END_DEBUG bt_shape = new btCylinderShapeZ( btVector3(params[0],params[0],params[1]/2) ); //DEBUG //std::cout << "BulletElement::BulletElement: Created CYLINDER ..." << std::endl; //END_DEBUG break; case MESH: //DEBUG //std::cout << "BulletElement::BulletElement: Create MESH ..." << std::endl; //END_DEBUG //bt_shape = new btConvexHullShape( (btScalar*) params.data(), //params.size()/3, //(int) 3*sizeof(double) ); bt_shape = new btConvexHullShape(); bt_shape->setMargin(0.05); for (int i=0; i<params.size(); i+=3){ //DEBUG //std::cout << "BulletElement::BulletElement: Adding point " << i/3 + 1 << std::endl; //END_DEBUG dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(params[i],params[i+1],params[i+2])); } //DEBUG //std::cout << "BulletElement::BulletElement: Created MESH ..." << std::endl; //END_DEBUG break; case CAPSULE: bt_shape = new btConvexHullShape(); dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,-params[1]/2)); dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,params[1]/2)); bt_shape->setMargin(params[0]); break; default: cerr << "Warning: Collision element has an unknown type " << shape << endl; //DEBUG //std::cout << "BulletElement::BulletElement: THROW" << std::endl; //END_DEBUG throw unknownShapeException(shape); break; } //DEBUG //cout << "BulletElement::BulletElement: Creating btCollisionObject" << endl; //END_DEBUG bt_obj = make_shared<btCollisionObject>(); //DEBUG //cout << "BulletElement::BulletElement: Setting bt_shape for bt_ob" << endl; //END_DEBUG bt_obj->setCollisionShape(bt_shape); //DEBUG //cout << "BulletElement::BulletElement: Setting world transform for bt_ob" << endl; //END_DEBUG setWorldTransform(Matrix4d::Identity()); //DEBUG //cout << "BulletElement::BulletElement: END" << std::endl; //END_DEBUG }
void Element::updateWorldTransform( const Eigen::Isometry3d& T_local_to_world_in) { setWorldTransform(T_local_to_world_in * (T_element_to_local)); }
bool PhysicsObject::init(unsigned int attributeIndex, short collisionFilterGroup) { if(attributeIndex < 0) { return false; } attributeIndex_ = attributeIndex; collisionFilterGroup_ = collisionFilterGroup; //Get the init data from a physics attribute AttributePtr<Attribute_Physics> ptr_physics = itrPhysics_.at(attributeIndex); btScalar mass = static_cast<btScalar>(ptr_physics->mass); //Resolve mass, local inertia of the collision shape, and also the collision shape itself. btCollisionShape* collisionShape = subClassSpecificCollisionShape(); if(collisionShape != nullptr) { setCollisionShape(collisionShape); } else { ERROR_MESSAGEBOX("Error in PhysicsObject::init. Expected collision shape pointer unexpectedly set to nullptr. Using default shape instead."); setCollisionShape(CollisionShapes::Instance()->getDefaultShape()); } btVector3 localInertia = subClassCalculateLocalInertiaHook(mass); setMassProps(mass, localInertia); //Set inverse mass and inverse local inertia updateInertiaTensor(); if((getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT)) { btTransform world; AttributePtr<Attribute_Spatial> ptr_spatial = itrPhysics_.at(attributeIndex_)->ptr_spatial; AttributePtr<Attribute_Position> ptr_position = ptr_spatial->ptr_position; world.setOrigin(convert(ptr_position->position)); world.setRotation(convert(ptr_spatial->rotation)); setWorldTransform(world); //Static physics objects: transform once } else { //Non-static physics objects: let a derived btMotionState handle transforms. MotionState* customMotionState = new MotionState(attributeIndex); setMotionState(customMotionState); setAngularVelocity(btVector3(ptr_physics->angularVelocity.x, ptr_physics->angularVelocity.y, ptr_physics->angularVelocity.z)); setLinearVelocity(btVector3(ptr_physics->linearVelocity.x, ptr_physics->linearVelocity.y, ptr_physics->linearVelocity.z)); //Gravity is set after "addRigidBody" for non-static physics objects } if(ptr_physics->collisionResponse) { setCollisionFlags(getCollisionFlags() & ~CF_NO_CONTACT_RESPONSE); //Activate collision response } else { setCollisionFlags(getCollisionFlags() | CF_NO_CONTACT_RESPONSE); //Deactivate collision response } return subClassSpecificInitHook(); }
/****************************************************************************** * Renders the current animation frame. ******************************************************************************/ bool ViewportSceneRenderer::renderFrame(FrameBuffer* frameBuffer, QProgressDialog* progress) { OVITO_ASSERT(_glcontext == QOpenGLContext::currentContext()); // Set up OpenGL state. OVITO_REPORT_OPENGL_ERRORS(); OVITO_CHECK_OPENGL(glDisable(GL_STENCIL_TEST)); OVITO_CHECK_OPENGL(glEnable(GL_DEPTH_TEST)); OVITO_CHECK_OPENGL(glDepthFunc(GL_LESS)); OVITO_CHECK_OPENGL(glDepthRange(0, 1)); OVITO_CHECK_OPENGL(glDepthMask(GL_TRUE)); OVITO_CHECK_OPENGL(glClearDepth(1)); OVITO_CHECK_OPENGL(glDisable(GL_SCISSOR_TEST)); _translucentPass = false; // Clear background. OVITO_CHECK_OPENGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); renderScene(); // Render visual 3D representation of the modifiers. renderModifiers(false); if(isInteractive()) { // Render construction grid. if(viewport()->isGridVisible()) renderGrid(); // Render input mode 3D overlays. MainWindow* mainWindow = renderDataset()->mainWindow(); if(mainWindow) { for(const auto& handler : mainWindow->viewportInputManager()->stack()) { if(handler->hasOverlay()) handler->renderOverlay3D(viewport(), this); } } } // Render visual 2D representation of the modifiers. renderModifiers(true); // Render input mode 2D overlays. if(isInteractive()) { MainWindow* mainWindow = renderDataset()->mainWindow(); if(mainWindow) { for(const auto& handler : mainWindow->viewportInputManager()->stack()) { if(handler->hasOverlay()) handler->renderOverlay2D(viewport(), this); } } } // Render translucent objects in a second pass. _translucentPass = true; for(auto& record : _translucentPrimitives) { setWorldTransform(std::get<0>(record)); std::get<1>(record)->render(this); } _translucentPrimitives.clear(); return true; }
/****************************************************************************** * Renders the construction grid. ******************************************************************************/ void ViewportSceneRenderer::renderGrid() { if(isPicking()) return; FloatType gridSpacing; Box2I gridRange; std::tie(gridSpacing, gridRange) = determineGridRange(viewport()); if(gridSpacing <= 0) return; // Determine how many grid lines need to be rendered. int xstart = gridRange.minc.x(); int ystart = gridRange.minc.y(); int numLinesX = gridRange.size(0) + 1; int numLinesY = gridRange.size(1) + 1; FloatType xstartF = (FloatType)xstart * gridSpacing; FloatType ystartF = (FloatType)ystart * gridSpacing; FloatType xendF = (FloatType)(xstart + numLinesX - 1) * gridSpacing; FloatType yendF = (FloatType)(ystart + numLinesY - 1) * gridSpacing; // Allocate vertex buffer. int numVertices = 2 * (numLinesX + numLinesY); std::unique_ptr<Point3[]> vertexPositions(new Point3[numVertices]); std::unique_ptr<ColorA[]> vertexColors(new ColorA[numVertices]); // Build lines array. ColorA color = Viewport::viewportColor(ViewportSettings::COLOR_GRID); ColorA majorColor = Viewport::viewportColor(ViewportSettings::COLOR_GRID_INTENS); ColorA majorMajorColor = Viewport::viewportColor(ViewportSettings::COLOR_GRID_AXIS); Point3* v = vertexPositions.get(); ColorA* c = vertexColors.get(); FloatType x = xstartF; for(int i = xstart; i < xstart + numLinesX; i++, x += gridSpacing, c += 2) { *v++ = Point3(x, ystartF, 0); *v++ = Point3(x, yendF, 0); if((i % 10) != 0) c[0] = c[1] = color; else if(i != 0) c[0] = c[1] = majorColor; else c[0] = c[1] = majorMajorColor; } FloatType y = ystartF; for(int i = ystart; i < ystart + numLinesY; i++, y += gridSpacing, c += 2) { *v++ = Point3(xstartF, y, 0); *v++ = Point3(xendF, y, 0); if((i % 10) != 0) c[0] = c[1] = color; else if(i != 0) c[0] = c[1] = majorColor; else c[0] = c[1] = majorMajorColor; } OVITO_ASSERT(c == vertexColors.get() + numVertices); // Render grid lines. setWorldTransform(viewport()->gridMatrix()); if(!_constructionGridGeometry || !_constructionGridGeometry->isValid(this)) _constructionGridGeometry = createLinePrimitive(); _constructionGridGeometry->setVertexCount(numVertices); _constructionGridGeometry->setVertexPositions(vertexPositions.get()); _constructionGridGeometry->setVertexColors(vertexColors.get()); _constructionGridGeometry->render(this); }
BulletElement::BulletElement(const Matrix4d& T_elem_to_link, Shape shape, const vector<double>& params, const string& group_name, bool use_margins) : T_elem_to_link(T_elem_to_link),shape(shape) { setGroupName(group_name); //DEBUG //std::cout << "BulletElement::BulletElement: START" << std::endl; //END_DEBUG btCollisionShape* bt_shape; double small_margin = 1e-9; switch (shape) { case BOX: { //DEBUG //std::cout << "BulletElement::BulletElement: Create BOX ..." << std::endl; //END_DEBUG btBoxShape bt_box( btVector3(params[0]/2,params[1]/2,params[2]/2) ); /* Strange things happen to the collision-normals when we use the * convex interface to the btBoxShape. Instead, we'll explicitly create * a btConvexHullShape. */ bt_shape = new btConvexHullShape(); if (use_margins) bt_shape->setMargin(0.05); else bt_shape->setMargin(small_margin); for (int i=0; i<8; ++i){ btVector3 vtx; bt_box.getVertex(i,vtx); dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(vtx); } //DEBUG //std::cout << "BulletElement::BulletElement: Created BOX" << std::endl; //END_DEBUG } break; case SPHERE: if (true || params[0] != 0) { //DEBUG //std::cout << "BulletElement::BulletElement: Create SPHERE ..." << std::endl; //END_DEBUG bt_shape = new btSphereShape(params[0]) ; //DEBUG //std::cout << "BulletElement::BulletElement: Created SPHERE" << std::endl; //END_DEBUG } else { //DEBUG //std::cout << "BulletElement::BulletElement: THROW" << std::endl; //END_DEBUG throw zeroRadiusSphereException(); } break; case CYLINDER: //DEBUG //std::cout << "BulletElement::BulletElement: Create CYLINDER ..." << std::endl; //END_DEBUG bt_shape = new btCylinderShapeZ( btVector3(params[0],params[0],params[1]/2) ); //DEBUG //std::cout << "BulletElement::BulletElement: Created CYLINDER ..." << std::endl; //END_DEBUG break; case MESH: //DEBUG //std::cout << "BulletElement::BulletElement: Create MESH ..." << std::endl; //END_DEBUG //bt_shape = new btConvexHullShape( (btScalar*) params.data(), //params.size()/3, //(int) 3*sizeof(double) ); bt_shape = new btConvexHullShape(); if (use_margins) bt_shape->setMargin(0.05); else bt_shape->setMargin(small_margin); for (int i=0; i<params.size(); i+=3){ //DEBUG //std::cout << "BulletElement::BulletElement: Adding point " << i/3 + 1 << std::endl; //END_DEBUG dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(params[i],params[i+1],params[i+2])); } //DEBUG //std::cout << "BulletElement::BulletElement: Created MESH ..." << std::endl; //END_DEBUG break; case CAPSULE: bt_shape = new btConvexHullShape(); dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,-params[1]/2)); dynamic_cast<btConvexHullShape*>(bt_shape)->addPoint(btVector3(0,0,params[1]/2)); bt_shape->setMargin(params[0]); break; default: cerr << "Warning: Collision element has an unknown type " << shape << endl; //DEBUG //std::cout << "BulletElement::BulletElement: THROW" << std::endl; //END_DEBUG throw unknownShapeException(shape); break; } //DEBUG //cout << "BulletElement::BulletElement: Creating btCollisionObject" << endl; //END_DEBUG bt_obj = make_shared<btCollisionObject>(); //DEBUG //cout << "BulletElement::BulletElement: Setting bt_shape for bt_ob" << endl; //END_DEBUG bt_obj->setCollisionShape(bt_shape); //DEBUG //cout << "BulletElement::BulletElement: Setting world transform for bt_ob" << endl; //END_DEBUG setWorldTransform(Matrix4d::Identity()); //DEBUG //cout << "BulletElement::BulletElement: END" << std::endl; //END_DEBUG }