void Engine::make_litcube(std::string name, glm::vec4 color, glm::vec3 scale, float mass, glm::vec3 position, glm::quat orientation) { Shader* shader = shaders["light1"]; Node* node = nodes[name] = new Node(nodes["scene"], position, orientation); VAO* vao = parse_obj_file("data/cube.obj", scale); std::vector<Uniform*> material; StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", color); material.push_back(mycolor); Renderable* renderable = new LitRenderObject(shader, node, vao, material); renderables.push_back(renderable); // mem vaos.push_back(vao); uniforms.push_back(mycolor); if (mass >= 0.f) { // physics btCollisionShape* cube_shape = new btBoxShape(from_vec3(scale/2.f)); physics->add_rigid_body( create_rigid_body(mass, node, cube_shape)); // mem collision_shapes.push_back(cube_shape); } }
void trimesh::create_physical_body( double x, double y, double z, double size_x, double size_y, double size_z, double mass, std::vector<double>& vertices_vec, std::vector<int>& indices_vec, const std::string name, manager& mgr) { world_id = mgr.ode_world(); space_id = mgr.ode_space(); //see if the trimesh data is cached so that we don't have to recreate it if(name.size() > 0) mesh_data = mgr.trimesh_cache().get_data(name); //if it is not cached then we create the trimesh data and put it in the cache if(!mesh_data) { trimesh_data* new_data = create_trimesh_data(vertices_vec, indices_vec); if(new_data == 0) { std::cout << "Error creating trimesh: " << name << std::endl; return; //TODO should throw instead... } mesh_data = trimesh_data_cache::data_ptr(new_data); mgr.trimesh_cache().cache_data(name, mesh_data); } //create the geom using the trimesh data geom_id = dCreateTriMesh(mgr.ode_space(),mesh_data->data_id, 0, 0, 0); object::set_geom_data(geom_id); //create and position the geom to represent the pysical shape of the rigid body dGeomSetPosition (geom_id, x, y, z); //we position it at the center relative to the body //if the mass is greater than 0 then the object is a dynamic mesh //so we have to create a rigid body if(mass > 0) { create_rigid_body(x, y, z, mgr); size[0] = size_x; size[1] = size_y; size[2] = size_z; set_mass(mass); dGeomSetBody (geom_id, body_id); } }
void MiuraModel::makeMiura(int vehicle_id, DisplayInterface * di, bool add_ghost, const btVector3 & origin, float rotation) { if (!vehicle_config_ptr) return; btRigidBody * ghost = 0; // miurabody0 if (add_ghost) { btTriangleIndexVertexArray * miurabody0_mi = new btTriangleIndexVertexArray(); for (unsigned int z=0;z<miurabody0_meshes.size();z++) { Mesh m = miurabody0_meshes.at(z); btVector3 * va = new btVector3[m.vertices_size/3]; unsigned int * ia = new unsigned int[m.faces_size/4]; int j = -1; for (unsigned int ind0 = 0; ind0 < m.vertices_size; ind0+=3 ) { va[++j].setValue(btScalar( *(m.p_vertices + ind0 + 0)), btScalar( *(m.p_vertices + ind0 + 1)), btScalar( *(m.p_vertices + ind0 + 2))); } int i = -1; for (unsigned int ind1 = 0; ind1 < m.faces_size; ind1+=12 ) { unsigned int c1 = *(m.p_faces + ind1 + 0); unsigned int c2 = *(m.p_faces + ind1 + 4); unsigned int c3 = *(m.p_faces + ind1 + 8); ia[++i] = c1-1; ia[++i] = c2-1; ia[++i] = c3-1; } btIndexedMesh * im = new btIndexedMesh(); im->m_numTriangles = m.faces_size/12; im->m_triangleIndexBase = reinterpret_cast<unsigned char*>(ia); im->m_triangleIndexStride = 3*sizeof(unsigned int); im->m_numVertices = j+1; im->m_vertexBase = reinterpret_cast<unsigned char*>(&va[0][0]); im->m_vertexStride = sizeof(btVector3); miurabody0_mi->addIndexedMesh(*im); ArraysTrack at; at.vertex_array = va; at.index_array = ia; at.indexed_mesh = im; arrays_track.push_back(at); } btGImpactMeshShape * miurabody0_shape = new btGImpactMeshShape(miurabody0_mi); miurabody0_shape->updateBound(); collision_shapes.push_back(miurabody0_shape); ArraysTrack at0; at0.mesh_interface = miurabody0_mi; arrays_track.push_back(at0); btTransform t; t.setIdentity(); t.setOrigin(origin); MyKinematicMotionState * motion_state = new MyKinematicMotionState(t); btRigidBody::btRigidBodyConstructionInfo rbi(0.,motion_state,miurabody0_shape); ghost = new btRigidBody(rbi); int * usrP = new int[2]; usrP[0] = vehicle_id + 1; // group id, don't collide inside the group, here group with id "1" usrP[1] = 2; // wheel raytest (MyVehicleRayResultCallback), "1" to process, "2" skip ghost->setUserPointer(usrP); ghost->setCollisionFlags( ghost->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); //ghost->setCollisionFlags( ghost->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); ghost->setActivationState(DISABLE_DEACTIVATION); m_dynamicsWorld->addRigidBody(ghost); } VehicleConfig * vehicle_config = new VehicleConfig; vehicle_config->vehicle_mass = btScalar(vehicle_config_ptr[0]); vehicle_config->max_suspension_force = btScalar(vehicle_config_ptr[1]); vehicle_config->suspension_stiffness = btScalar(vehicle_config_ptr[2]); vehicle_config->damping_relaxation = btScalar(vehicle_config_ptr[3]); vehicle_config->damping_compression = btScalar(vehicle_config_ptr[4]); vehicle_config->suspension_rest_length = btScalar(vehicle_config_ptr[5]); vehicle_config->max_suspension_travel = btScalar(vehicle_config_ptr[6]); vehicle_config->roll_influence = btScalar(vehicle_config_ptr[7]); vehicle_config->inertia_coefficient = btScalar(vehicle_config_ptr[8]); //= btScalar(vehicle_config_ptr[ 9]); //= btScalar(vehicle_config_ptr[10]); vehicle_config->max_braking_force = btScalar(vehicle_config_ptr[11]); vehicle_config->steering_clamp = btScalar(vehicle_config_ptr[12]); vehicle_config->chassis_mass_y_shift = btScalar(vehicle_config_ptr[13]); vehicle_config->chassis_mass_z_shift = btScalar(vehicle_config_ptr[14]); vehicle_config->fwheel_radius = btScalar(vehicle_config_ptr[15]); vehicle_config->rwheel_radius = btScalar(vehicle_config_ptr[16]); vehicle_config->fwheel_width = btScalar(vehicle_config_ptr[17]); vehicle_config->rwheel_width = btScalar(vehicle_config_ptr[18]); vehicle_config->chassis_friction = btScalar(vehicle_config_ptr[19]); vehicle_config->chassis_restitution = btScalar(vehicle_config_ptr[20]); vehicle_config->chassis_angular_dump = btScalar(vehicle_config_ptr[21]); vehicle_config->chassis_linear_dump = btScalar(vehicle_config_ptr[22]); vehicle_config->steering_wheel_factor = btScalar(vehicle_config_ptr[23]); vehicle_config->steering_wheel_sensitivity = btScalar(vehicle_config_ptr[30]); // = btScalar(vehicle_config_ptr[24]); // = btScalar(vehicle_config_ptr[25]); vehicle_config->Crr = btScalar(vehicle_config_ptr[29]); vehicle_config->vehicle_steering = btScalar(0.0); vehicle_config->origin = btVector3(origin); vehicle_config->right_index = 0; vehicle_config->up_index = 1; vehicle_config->forward_index = 2; vehicle_config->wheel_direction_CS0 = btVector3(btScalar(0.0), btScalar(-1.0), btScalar(0.0)); vehicle_config->wheel_axle_CS = btVector3(btScalar(-1.0), btScalar(0.0), btScalar(0.0)); vehicle_config->steering_wheel_axis = btVector3(btScalar(0.0), btScalar(0.371), btScalar(-0.928)); //vehicle_config->steering_wheel_pos = btVector3(world_loc_miura_rul[0],world_loc_miura_rul[1],world_loc_miura_rul[2]); //vehicle_config->driver_pos = btVector3(btScalar(world_loc_miura[0] + 0.35f), // btScalar(world_loc_miura[1] + 0.3f - c->chassis_mass_y_shift), // btScalar(world_loc_miura[2] - 0.35f - c->chassis_mass_z_shift)); btScalar f_wheel_y = btScalar(-0.308666); btScalar r_wheel_y = f_wheel_y; vehicle_config->wheel_fr_v = btVector3( btScalar(-0.714463), -(vehicle_config->chassis_mass_y_shift) + f_wheel_y, btScalar(1.186053) - vehicle_config->chassis_mass_z_shift); vehicle_config->wheel_fl_v = btVector3( btScalar(0.714463), -(vehicle_config->chassis_mass_y_shift) + f_wheel_y, btScalar(1.186053) - vehicle_config->chassis_mass_z_shift); vehicle_config->wheel_br_v = btVector3( btScalar(-0.714463), -(vehicle_config->chassis_mass_y_shift) + r_wheel_y, btScalar(-1.313947) - vehicle_config->chassis_mass_z_shift); vehicle_config->wheel_bl_v = btVector3( btScalar(0.714463), -(vehicle_config->chassis_mass_y_shift) + r_wheel_y, btScalar(-1.313947) - vehicle_config->chassis_mass_z_shift); ////////////////////////////////////////////////////// { int vertex_stride = sizeof(btVector3); btVector3 * vertex_array = new btVector3[vertices_size_miura_proxy/3]; int j = -1; for ( int ind = 0; ind < vertices_size_miura_proxy; ind+=3 ) { vertex_array[++j].setValue(btScalar( *(p_vertices_miura_proxy+ind+0)), btScalar( *(p_vertices_miura_proxy+ind+1)), btScalar( *(p_vertices_miura_proxy+ind+2))); } btCollisionShape * shape = new btConvexHullShape((btScalar *) &vertex_array[0][0],vertices_size_miura_proxy/3,vertex_stride); ArraysTrack bo; bo.vertex_array = vertex_array; arrays_track.push_back(bo); btCompoundShape * compound = new btCompoundShape(); btTransform chassis_local_trans; chassis_local_trans.setIdentity(); chassis_local_trans.setOrigin(btVector3(btScalar(0.0), -(vehicle_config->chassis_mass_y_shift), -(vehicle_config->chassis_mass_z_shift))); compound->addChildShape(chassis_local_trans,shape); collision_shapes.push_back(compound); btTransform compound_trans; compound_trans.setIdentity(); compound_trans.setOrigin(vehicle_config->origin); btQuaternion q(btVector3(btScalar(0.),btScalar(1.),btScalar(0.)),btScalar(rotation)); compound_trans.setRotation(q); btRigidBody * chassis; chassis = create_rigid_body(vehicle_config->vehicle_mass, compound_trans, compound, vehicle_config->chassis_friction, vehicle_config->chassis_restitution, vehicle_config->chassis_angular_dump, vehicle_config->chassis_linear_dump); chassis->setLinearVelocity(btVector3(btScalar(0.0),btScalar(0.0),btScalar(0.0))); chassis->setAngularVelocity(btVector3(btScalar(0.0),btScalar(0.0),btScalar(0.0))); int * usrP = new int[2]; usrP[0] = vehicle_id + 1;// group id, don't collide inside the group, here group with id "1" usrP[1] = 1;// wheel raytest (MyVehicleRayResultCallback), "2" to skip chassis->setUserPointer(usrP); RaycastCar * vehicle = new RaycastCar(chassis); vehicle->m_dynamicsWorld = m_dynamicsWorld; chassis->setActivationState(DISABLE_DEACTIVATION); vehicle->setCoordinateSystem(vehicle_config->right_index, vehicle_config->up_index, vehicle_config->forward_index); vehicle->m_Crr = vehicle_config->Crr; vehicle->m_inertia_coef = vehicle_config->inertia_coefficient; for (int x=0;x<4;x++) vehicle->addWheel(vehicle_config, x); VehicleObject * vo = new VehicleObject; vo->set_raycast_vehicle(vehicle); vo->set_compound_shape(compound); vo->set_chassis_shape(shape); vo->set_chassis_body(chassis); if (add_ghost) vo->set_ghost_body(ghost); vo->set_vehicle_config(vehicle_config); vo->set_draw_object(di); vo->draw_wheel_fr = draw_wheel_fr; vo->draw_wheel_fl = draw_wheel_fl; vo->draw_wheel_rr = draw_wheel_rr; vo->draw_wheel_rl = draw_wheel_rl; if (vehicles.size() <= vehicle_id) { vehicles.push_back(vo); } else { vehicles[vehicle_id] = vo; } m_dynamicsWorld->addAction(vehicle); } ///////////////////////////////////////////////////// }
core::RigidBody create_rigid_body(Hierarchy h) { return create_rigid_body(Hierarchies(1,h), h->get_name()+" rigid body"); }
void Engine::init_scene() { Node* scene = nodes["scene"] = new Node(NULL); // shaders // // "simple_shader" shaders["simple_shader"] = make_shader("shaders/p_v.glsl", "shaders/unicolor_f.glsl"); // "light1" { Shader* shader = shaders["light1"] = make_shader("shaders/pn_v.glsl", "shaders/light1_f.glsl"); // TODO put uniforms in "material"-class or something? set_uniform(shader, "mycolor", glm::vec4(1.f)); set_uniform(shader, "ambient_intensity", glm::vec4(.1f,.1f,.1f,1.f)); set_uniform(shader, "diffuse_color", glm::vec4(.5f,.5f,.5f,1.f)); set_uniform(shader, "specular_color", glm::vec4(1.f,1.f,1.f,1.f)); set_uniform(shader, "atten_k", .04f); set_uniform(shader, "gauss_k", .1f); } // objects // // grid { Shader* shader = shaders["simple_shader"]; Node* node = nodes["grid"] = new Node(scene); int no = 5; glm::vec3 scale = glm::vec3(20.f); VAO* vao = create_grid(no, scale); std::vector<Uniform*> material; glm::vec4 white = glm::vec4(1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", white); material.push_back(mycolor); renderables.push_back( new BasicRenderObject(shader, node, vao, material)); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // redcube { Shader* shader = shaders["light1"]; Node* node = nodes["redcube"] = new Node(scene); node->position = glm::vec3(.5f,.5f,-1.7f); glm::vec3 scale = glm::vec3(.05f); VAO* vao = create_cube_with_normals(scale); std::vector<Uniform*> material; glm::vec4 red = glm::vec4(1.f,0.f,.5f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", red); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // physics btCollisionShape* cube_shape = new btBoxShape(from_vec3(scale/2.f)); float mass = 0.f; redcube_rb = create_rigid_body(mass, node, cube_shape); physics->add_rigid_body(redcube_rb); // mem vaos.push_back(vao); uniforms.push_back(mycolor); collision_shapes.push_back(cube_shape); } make_litcube("cyancube", glm::vec4(0.f, 1.f, 1.f, 1.f), glm::vec3(0.05f)); nodes["cyancube"]->orientation = glm::angleAxis(glm::radians(45.f), glm::normalize(glm::vec3(-1.f, 1.f, 1.f))); make_litcube("yellowcube", glm::vec4(1.f, 1.f, 0.f, 1.f), glm::vec3(0.05f)); nodes["yellowcube"]->orientation = nodes["cyancube"]->orientation; make_litcube("bluecube", glm::vec4(0.f, 0.f, 1.f, 1.f), glm::vec3(1.f), 30.f, glm::vec3(0.f, 1.5f, -5.f)); // lightcube { Shader* shader = shaders["simple_shader"]; Node* node = nodes["lightcube"] = new Node(scene); node->position = glm::vec3(0.f, 1.f, 0.f); glm::vec3 scale = glm::vec3(.3f,.3f,.3f); VAO* vao = create_cube(scale); std::vector<Uniform*> material; glm::vec4 white = glm::vec4(1.f,1.f,1.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", white); material.push_back(mycolor); renderables.push_back( new BasicRenderObject(shader, node, vao, material)); // sync point light with position PointLight light0(node, glm::vec4(.7f,.7f,.7f,1.f)); set_uniform(shaders["light1"], "light.position", glm::vec3(light0.get_position())); set_uniform(shaders["light1"], "light.intensity", light0.get_intensity()); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // plane { Shader* shader = shaders["light1"]; Node* node = nodes["plane"] = new Node(scene); node->position = glm::vec3(0.f, -.5f, 0.f); glm::vec3 scale = glm::vec3(20.f, 1.f, 20.f); VAO* vao = create_cube_with_normals(scale); std::vector<Uniform*> material; glm::vec4 goldish = glm::vec4(1.f,1.f,0.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", goldish); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // physics btCollisionShape* shape = new btBoxShape(from_vec3(scale/2.f)); float mass = 0.f; btRigidBody* rigid_body = create_rigid_body(mass, node, shape); physics->add_rigid_body(rigid_body); // mem uniforms.push_back(mycolor); vaos.push_back(vao); collision_shapes.push_back(shape); } // bound { Shader* shader = shaders["light1"]; Node* node = nodes["bound"] = new Node(scene); glm::vec3 scale = glm::vec3(20.f); bool face_inward = true; VAO* vao = create_cube_with_normals(scale, face_inward); std::vector<Uniform*> material; glm::vec4 greenblueish = glm::vec4(0.f,1.f,1.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", greenblueish); material.push_back(mycolor); renderables.push_back( new LitRenderObject(shader, node, vao, material)); // mem vaos.push_back(vao); uniforms.push_back(mycolor); } // roboarm { nodes["roboarm0"] = new Node(scene); nodes["roboarm1"] = new Node(scene); nodes["roboarm2"] = new Node(scene); nodes["roboarm3"] = new Node(scene); glm::vec3 scale = glm::vec3(0.1f, 0.4f, 0.1f); nodes["roboarm0"]->position = glm::vec3(0.f, 1.f, -2.f); //nodes["roboarm0"]->orientation = // glm::angleAxis(glm::radians(180.f), glm::vec3(1.f, 0.f, 0.f)); nodes["roboarm1"]->position = nodes["roboarm0"]->position + nodes["roboarm0"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm1"]->orientation = nodes["roboarm0"]->orientation; nodes["roboarm2"]->position = nodes["roboarm1"]->position + nodes["roboarm1"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm2"]->orientation = nodes["roboarm1"]->orientation; nodes["roboarm3"]->position = nodes["roboarm2"]->position + nodes["roboarm2"]->orientation * glm::vec3(0.f, scale.y, 0.f); nodes["roboarm3"]->orientation = nodes["roboarm2"]->orientation; // render { Shader* shader = shaders["light1"]; glm::vec4 black = glm::vec4(0.f,0.f,0.f,1.f); StoredUniform<glm::vec4>* mycolor = new StoredUniform<glm::vec4>(shader, "mycolor", black); std::vector<Uniform*> material; material.push_back(mycolor); // TODO use rounder shapes... VAO* vao = create_cube_with_normals(scale); auto make_renderable = [&shader, &material, &vao] (Node* node) { return new LitRenderObject(shader, node, vao, material); }; renderables.insert(renderables.end(), { make_renderable(nodes["roboarm0"]), make_renderable(nodes["roboarm1"]), make_renderable(nodes["roboarm2"]), make_renderable(nodes["roboarm3"]), } ); // mem uniforms.push_back(mycolor); vaos.push_back(vao); } btCollisionShape *shape = new btBoxShape(from_vec3(scale/2.f)); float density = 1000.f, volume = scale.x * scale.y * scale.z, mass = density * volume; // mem collision_shapes.push_back(shape); btRigidBody *rb0 = create_rigid_body(0.f, nodes["roboarm0"], shape), *rb1 = create_rigid_body(mass, nodes["roboarm1"], shape), *rb2 = create_rigid_body(mass, nodes["roboarm2"], shape), *rb3 = create_rigid_body(mass, nodes["roboarm3"], shape); rb1->setActivationState(DISABLE_DEACTIVATION); rb2->setActivationState(DISABLE_DEACTIVATION); rb3->setActivationState(DISABLE_DEACTIVATION); physics->add_rigid_body(rb0); physics->add_rigid_body(rb1); physics->add_rigid_body(rb2); physics->add_rigid_body(rb3); btMatrix3x3 rot; rot.setIdentity(); btTransform trans_up(rot, btVector3(0.f, scale.y/2, 0.f)), trans_down(rot, btVector3(0.f, -scale.y/2, 0.f)); rc1 = new btHingeConstraint(*rb0, *rb1, trans_up, trans_down); rc2 = new btHingeConstraint(*rb1, *rb2, trans_up, trans_down); rc3 = new btHingeConstraint(*rb2, *rb3, trans_up, trans_down); float pi = glm::pi<float>(); rc1->setLimit(-pi/2, pi/2); rc2->setLimit(-pi/2, pi/2); rc3->setLimit(-pi/2, pi/2); bool intercollision = false; physics->add_constraint(rc1, intercollision); physics->add_constraint(rc2, intercollision); physics->add_constraint(rc3, intercollision); roboarm0 = new KinematicChain(nullptr, rb0, nullptr); roboarm1 = new KinematicChain(roboarm0, rb1, rc1); roboarm2 = new KinematicChain(roboarm1, rb2, rc2); roboarm3 = new KinematicChain(roboarm2, rb3, rc3); } }