it is done, the Spring is now useble as a class. I would have made it a IJoint class, but I don't get how they are actually working.
Windows Binary & Source
http://www.freetimestudio.de/IrrNewt_Springs.zip
CSpring.h
Code: Select all
#ifndef CSPRING_H_INCLUDED
#define CSPRING_H_INCLUDED
#include <IrrNewt.hpp>
#include <irrlicht.h>
using namespace irr;
class CSpring{
private:
newton::IBody *Body_Parent;
newton::IBody *Body_Child;
f32 Strength;
f32 Length;
public:
CSpring();
CSpring(newton::IBody *parent,newton::IBody *child,f32 strength=1,f32 length = -1);
~CSpring();
void update();
void setStrength(f32 pstrength);
f32 getStrength();
void setLength(f32 plength);
f32 getLength();
void setParent(newton::IBody *pparent);
newton::IBody *getParent();
void setChild(newton::IBody *pchild);
newton::IBody *getChild();
void drawDebugData(video::IVideoDriver *driver);
};
#endif // CSPRING_H_INCLUDED
Code: Select all
#include "CSpring.h"
CSpring::CSpring(){
Body_Parent = 0;
Body_Child = 0;
Strength = 1;
Length = 0;
}
CSpring::CSpring(newton::IBody *parent,newton::IBody *child,f32 strength,f32 length){
Body_Parent = parent;
Body_Child = child;
Strength = strength;
Length = length;
if(Length<0){
if(Body_Parent!=0 && Body_Child!=0){
core::line3d<f32> line;
line.start = Body_Parent->getNode()->getAbsolutePosition();
line.end = Body_Child->getNode()->getAbsolutePosition();
Length = line.getLength();
}
}
}
CSpring::~CSpring(){
Body_Parent = 0;
Body_Child = 0;
}
void CSpring::update(){
if(Body_Child!=0 && Body_Parent!=0){
core::line3d<f32> line;
line.start = Body_Parent->getNode()->getAbsolutePosition();
line.end = Body_Child->getNode()->getAbsolutePosition();
core::vector3df force_direction = line.getVector().normalize();
f32 curlength = line.getLength();
f32 factor = curlength-Length;
core::vector3df force = force_direction*factor;
Body_Parent->addGlobalForce(Strength*force,line.end);
Body_Child->addGlobalForce(-Strength*force,line.end);
}
}
void CSpring::setStrength(f32 pstrength){
Strength = pstrength;
}
f32 CSpring::getStrength(){
return Strength;
}
void CSpring::setLength(f32 plength){
Length = plength;
}
f32 CSpring::getLength(){
return Length;
}
void CSpring::setParent(newton::IBody *pparent){
Body_Parent = pparent;
}
newton::IBody *CSpring::getParent(){
return Body_Parent;
}
void CSpring::setChild(newton::IBody *pchild){
Body_Child = pchild;
}
newton::IBody *CSpring::getChild(){
return Body_Child;
}
void CSpring::drawDebugData(video::IVideoDriver *driver){
if(Body_Child!=0 && Body_Parent!=0){
video::SMaterial material;
material.Lighting = false;
material.Thickness = 3;
driver->setMaterial(material);
driver->setTransform(video::ETS_WORLD,core::matrix4());
driver->draw3DLine(Body_Parent->getNode()->getAbsolutePosition(),Body_Child->getNode()->getAbsolutePosition(),video::SColor(255,255,255,0));
}
}
Code: Select all
//include haders and link libraries
#include <IrrNewt.hpp>
#include <irrlicht.h>
using namespace irr;
#include "CSpring.h"
//irrlicht variables
IrrlichtDevice* device;
video::IVideoDriver* driver;
scene::ISceneManager* smgr;
scene::ICameraSceneNode* camera;
//level body
irr::newton::IBody* level_body;
//physics world
irr::newton::IWorld* p_world;
f32 idlelength;
f32 Strength;
//-----------------------------------------------------------------
//the event receiver
class MyEventReceiver:public IEventReceiver {
public:
virtual bool OnEvent(const SEvent& event) {
if(event.EventType == EET_KEY_INPUT_EVENT) {
if(event.KeyInput.PressedDown == false) { //pressed down false
if(event.KeyInput.Key==KEY_KEY_W){
idlelength++;
printf("Idle Length: %i\n",(int)idlelength);
}
if(event.KeyInput.Key==KEY_KEY_S){
idlelength--;
printf("Idle Length: %i\n",(int)idlelength);
}
if(event.KeyInput.Key==KEY_KEY_Q){
Strength+=0.1;
printf("Strength: %f\n",Strength);
}
if(event.KeyInput.Key==KEY_KEY_A){
Strength-=0.1;
printf("Strength: %f\n",Strength);
}
//exit
if(event.KeyInput.Key==KEY_ESCAPE)
device->closeDevice();
}//else if(event.KeyInput.PressedDown == false) {
}
return false;
}
}my_event_receiver;
int main(int argc, char** argv) {
//Get all the framework running
device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(800,600), 32,false,false,true);
smgr=device->getSceneManager();
driver=device->getVideoDriver();
p_world=irr::newton::createPhysicsWorld(device);
device->setEventReceiver(&my_event_receiver);
//Scene stuff
camera=smgr->addCameraSceneNodeFPS();
camera->setPosition(core::vector3df(0,55,-50));
smgr->addLightSceneNode(0,core::vector3df(0,100,-100));
//Some ground
scene::ISceneNode* world_node = smgr->addCubeSceneNode(2);
world_node->setScale(core::vector3df(102,1,102));
world_node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS,true);
world_node->setAutomaticCulling(scene::EAC_OFF);
irr::newton::SBodyFromNode levelData;
levelData.Node = world_node;
levelData.Mass = 0;
levelData.Type = newton::EBT_PRIMITIVE_BOX;
level_body = p_world->createBody(levelData);
irr::newton::IMaterial* ground_material= p_world->createMaterial();
level_body->setMaterial(ground_material);
//Hooks for the net
irr::newton::IMaterial* hook_material= p_world->createMaterial();
//First hook
scene::ISceneNode* hook_node = smgr->addCubeSceneNode(2);
hook_node->setPosition(core::vector3df(-20,60,0));
irr::newton::SBodyFromNode hook_data1;
hook_data1.Node = hook_node;
hook_data1.Mass = 0;
hook_data1.Type = newton::EBT_PRIMITIVE_BOX;
irr::newton::IBody* hook_body1 = p_world->createBody(hook_data1);
hook_body1->setMaterial(hook_material);
//Second hook
scene::ISceneNode* hook_node2 = smgr->addCubeSceneNode(2);
hook_node2->setPosition(core::vector3df(20,60,0));
irr::newton::SBodyFromNode hook_data2;
hook_data2.Node = hook_node2;
hook_data2.Mass = 0;
hook_data2.Type = newton::EBT_PRIMITIVE_BOX;
irr::newton::IBody* hook_body2 = p_world->createBody(hook_data2);
hook_body2->setMaterial(hook_material);
//Spheres in the net
irr::newton::IMaterial* sphere_material;
sphere_material= p_world->createMaterial();
sphere_material->setElasticity(ground_material, 1);
//Sphere 1
scene::ISceneNode* sphere_node1;
irr::newton::SBodyFromNode sphereData;
irr::newton::IBody *sphere_body;
sphere_node1 = smgr->addSphereSceneNode(2);
sphere_node1->setPosition(core::vector3df(-20,20,0));
sphereData.Node = sphere_node1;
sphereData.Type = newton::EBT_PRIMITIVE_ELLIPSOID;
sphereData.Mass=10;
sphere_body = p_world->createBody(sphereData);
sphere_body->addForceContinuous(core::vector3df(0,-9.81,0));//gravity
sphere_body->addForce(core::vector3df(5,0,5)); //give it a little push
sphere_body->setMaterial(sphere_material);
//Sphere 2
scene::ISceneNode* sphere_node2;
irr::newton::SBodyFromNode sphereData2;
irr::newton::IBody *sphere_body2;
sphere_node2 = smgr->addSphereSceneNode(2);
sphere_node2->setPosition(core::vector3df(20,20,0));
sphereData2.Node = sphere_node2;
sphereData2.Mass=10;
sphereData2.Type = newton::EBT_PRIMITIVE_ELLIPSOID;
sphere_body2 = p_world->createBody(sphereData2);
sphere_body2->addForceContinuous(core::vector3df(0,-9.81,0)); //gravity
sphere_material= p_world->createMaterial();
sphere_body2->setMaterial(sphere_material);
//Set up the spring system
core::list<CSpring*> list_springs = core::list<CSpring*>();
//Connect everything with everything
idlelength = 40.0f;
Strength = 1;
CSpring *spring = new CSpring(sphere_body,sphere_body2);
list_springs.push_back(spring);
CSpring *spring2 = new CSpring(sphere_body,hook_body2);
spring2->setLength(20);
list_springs.push_back(spring2);
CSpring *spring3 = new CSpring(sphere_body2,hook_body1);
spring3->setLength(20);
list_springs.push_back(spring3);
CSpring *spring4 = new CSpring(sphere_body,hook_body1);
spring4->setLength(20);
list_springs.push_back(spring4);
CSpring *spring5 = new CSpring(sphere_body2,hook_body2);
spring5->setLength(20);
list_springs.push_back(spring5);
printf("\n\n\nChange the middle spring's idle length with W and S. Current Length is: 20\n");
printf("Change the middle spring's strength with Q and A. Current Strength is: 1\n");
//Here we go
while(device->run()) {
driver->beginScene(true,true,video::SColor(0,0,0,0));
video::SMaterial material;
material.Lighting = false;
material.Thickness = 3;
driver->setMaterial(material);
driver->setTransform(video::ETS_WORLD,core::matrix4());
video::SColor drawcolor=video::SColor(255,200,100,0);
driver->draw3DLine(hook_node->getPosition(),sphere_node1->getPosition(),drawcolor);
driver->draw3DLine(hook_node2->getPosition(),sphere_node2->getPosition(),drawcolor);
spring->setStrength(Strength);
spring->setLength(idlelength);
core::list<CSpring*>::Iterator it_spring = list_springs.begin();
for(;it_spring!=list_springs.end();it_spring++){
(*it_spring)->update();
(*it_spring)->drawDebugData(driver);
}
p_world->update();
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
I also have a question. I want to create a vehicle, but I don't want to use the inbuild ICar class (because it can just handle "simple" vehicles), so I started to create an own Car as a basis. Problem is, it does barely move. I tried every possible friction configuration and set different masses for the cassis/tires or torque, but it either does not change much or the car gets totally out of control and spins around like crazy. Any ideas what could be wrong?
exe and media: http://www.freetimestudio.de/Car.zip
Code: Select all
//include haders and link libraries
#include <IrrNewt.hpp>
#include <irrlicht.h>
using namespace irr;
//irrlicht variables
IrrlichtDevice* device;
video::IVideoDriver* driver;
scene::ISceneManager* smgr;
scene::ICameraSceneNode* camera;
//level body
irr::newton::IBody* level_body;
//physics world
irr::newton::IWorld* p_world;
int main(int argc, char** argv) {
//Get all the framework running
device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(800,600), 32,false,false,true);
smgr=device->getSceneManager();
driver=device->getVideoDriver();
p_world=irr::newton::createPhysicsWorld(device);
//Scene stuff
camera=smgr->addCameraSceneNodeFPS(0,100,0.1);
camera->setPosition(core::vector3df(-50,20,0));
camera->setRotation(core::vector3df(0,90,0));
smgr->addLightSceneNode(0,core::vector3df(0,100,-100));
//Some ground
scene::ISceneNode* world_node = smgr->addCubeSceneNode(2);
world_node->setScale(core::vector3df(50,3,50));
world_node->setPosition(core::vector3df(0,-15,0));
world_node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS,true);
world_node->setAutomaticCulling(scene::EAC_OFF);
irr::newton::SBodyFromNode levelData;
levelData.Node = world_node;
levelData.Mass = 0;
levelData.Type = newton::EBT_PRIMITIVE_BOX;
level_body = p_world->createBody(levelData);
irr::newton::IMaterial* ground_material= p_world->createMaterial();
level_body->setMaterial(ground_material);
scene::IMeshSceneNode *node_cassis = smgr->addMeshSceneNode(smgr->getMesh("media/car.b3d"));
node_cassis->setScale(core::vector3df(10,10,10));
node_cassis->setMaterialFlag(video::EMF_NORMALIZE_NORMALS,true);
newton::SBodyFromNode data_cassis;
data_cassis.Node = node_cassis;
data_cassis.Mass =1;
data_cassis.Mesh = node_cassis->getMesh();
data_cassis.Type = newton::EBT_CONVEX_HULL;
newton::IBody *body_cassis = p_world->createBody(data_cassis);
body_cassis->addForceContinuous(core::vector3df(0,-9.81,0));
//Creating four wheels
irr::newton::IMaterial* material_wheel= p_world->createMaterial();
material_wheel->setFriction(ground_material,1,0.1);
scene::IMeshSceneNode *node_wheel[4];
newton::IBody *body_wheel[4];
for(int i = 0;i<4;i++){
node_wheel[i] = smgr->addMeshSceneNode(smgr->getMesh("media/tire.b3d"));
node_wheel[i]->setScale(core::vector3df(10,10,10));
node_wheel[i]->setRotation(core::vector3df(0,0,90));
node_wheel[i]->setPosition(core::vector3df(0,10,0));
node_wheel[i]->setMaterialFlag(video::EMF_NORMALIZE_NORMALS,true);
newton::SBodyFromNode data_wheel;
data_wheel.Node = node_wheel[i];
data_wheel.Mesh = node_wheel[i]->getMesh();
data_wheel.Type = newton::EBT_PRIMITIVE_CYLINDER;
body_wheel[i] = p_world->createBody(data_wheel);
body_wheel[i]->addForceContinuous(core::vector3df(0,-9.81,0));
body_wheel[i]->setMaterial(material_wheel);
}
body_wheel[0]->setPosition(core::vector3df(4,-1.3,5.5));
body_wheel[0]->setRotation(core::vector3df(180,00,90));
body_wheel[1]->setPosition(core::vector3df(-4,-1.3,5.5));
body_wheel[2]->setPosition(core::vector3df(4,-1.3,-5.5));
body_wheel[2]->setRotation(core::vector3df(180,00,90));
body_wheel[3]->setPosition(core::vector3df(-4,-1.3,-5.5));
//Connecting them with the cassis
for(int i=0;i<4;i++){
core::vector3df pivot,pin0,pin1;
pivot=body_wheel[i]->getPosition();
pin0.set(0.0f,0.0f,0.0f);
irr::newton::SJointHinge joint;
joint.PinDir.set(1.0f,0.0f,0.0f);
joint.ParentBody=body_cassis;
joint.ChildBody=body_wheel[i];
joint.Pivot=pivot;
newton::IJointHinge* bjoint=p_world->createJoint(joint);
bjoint->setCollisionState(false);
}
body_cassis->setPosition(core::vector3df(0,8,0));
//Here we go
while(device->run()) {
//"Motor"
for(int i=2;i<4;i++){
body_wheel[i]->setTorque(core::vector3df(3,0,0));
}
driver->beginScene(true,true,video::SColor(0,0,0,0));
p_world->update();
smgr->drawAll();
p_world->drawAllDebugInfos();
driver->endScene();
}
device->drop();
return 0;
}