Posted: Sat Apr 14, 2007 10:42 am
well, I see... It was realy simple to compie the dll.. no problem...(no big problems^^) I think that irrNewt realy rocks.. but i´m not sure.. have to test it some more.
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
i think this can be solved by set material stifness higher. however this is due to very high gravity (a low gravity make the body jump the stair without my code (newton do this automatically))the player will sink into the ground
i do this check (try to press jump button and mantain it pressed). But evidently this doesn't work if you press jump and crounch fast. i will check itIf you rapidly press the stand/crouch button, the player start flying. so you have to check, if the objekt stands on the ground befor you add the up force to it..
does it shoot the character to a very high level?but one problem left: sometimes the stair detection does strange things like shooting the objekt direckt to the moon or stuff...
i never talked about the jump button^^ the jump works all fine...i do this check (try to press jump button and mantain it pressed). But evidently this doesn't work if you press jump and crounch fast. i will check itIf you rapidly press the stand/crouch button, the player start flying. so you have to check, if the objekt stands on the ground befor you add the up force to it..
Funktions makes the problems..stand/crouch
Code: Select all
irr::f32 irr::newton::IUtils::getDistanceFromFloor(newton::IBody* body, irr::newton::SIntersectionPoint& i_point) {
core::aabbox3d<f32> box = body->calculateAABB();
core::line3d<f32> line(box.MinEdge,core::vector3df());
line.end = line.start;
line.end.Y -= 999999.9f;
i_point=
this->world->getCollisionManager()->getCollisionFirstPointEx(line);
return i_point.point.getDistanceFrom(line.start);
}
Code: Select all
bool irr::newton::ICharacterController::stand(irr::f32 speed, irr::f32 distanceFromFloor) {
if(this->is_crouching) {
this->is_crouching=false;
this->setScaleBody(core::vector3df(1,1,1));
//velocity to make the body standing
newton::SIntersectionPoint point;
f32 dist = this->world->getUtils()->getDistanceFromFloor(this, point);
if(dist <= distanceFromFloor) {
core::vector3df vel = this->getVelocity();
vel.Y += speed;
this->setVelocity(vel);
}
return true;
}
return false;
}
Code: Select all
bool stand(irr::f32 speed, irr::f32 distanceFromFloor=27);
Code: Select all
//There is a stair!!! Make the body climb it!!!
core::vector3df vel = p_node->getVelocity();
vel += p_node->getClimbStairForce();
p_node->setVelocity(vel);
Code: Select all
//There is a stair!!! Make the body climb it!!!
core::vector3df vel = p_node->getVelocity();
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
Code: Select all
//There is a stair!!! Make the body climb it!!!
core::vector3df vel = p_node->getVelocity();
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
Code: Select all
newton::SIntersectionPoint point;
f32 dist = this->world->getUtils()->getDistanceFromFloor(this, point);
if(dist <= distanceFromFloor)
{
core::vector3df vel = p_node->getVelocity();
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
}
uhm? i have recompiled irrnewt and character demo and when the character is crouching it doesn't climb stairs (of course you make the character climb a stair when crouching by change max height stair parameter in the demo)but the char still thinkst everything is a stair while crouching..
Code: Select all
//There is a stair!!! Make the body climb it!!!
core::vector3df vel = p_node->getVelocity();
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
because stair detection already use 2 collision detecion and distanceFromFloor use collision detection = 3 collision detections, wich is too slow.newton::SIntersectionPoint point;
f32 dist = this->world->getUtils()->getDistanceFromFloor(this, point);
if(dist <= distanceFromFloor)
{
core::vector3df vel = p_node->getVelocity();
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
}
Code: Select all
//character control callbacks
void irr::newton::Hidden::CharacterControllerSetForceAndTorqueEvent (
const NewtonBody* body) {
//core::vector3df velocity=p_node->getVelocity();
//core::vector3df last_force_continuos=p_node->force_continuos;
//INTERPOLATE VELOCITY WITH FORCE
/*
if(p_node->apply_force_if_not_air_borne) {
core::vector3df last_force_continuous=p_node->force_continuos;
p_node->force_continuos=core::vector3df();
core::aabbox3d<f32> box=p_node->node->getTransformedBoundingBox();
core::line3d<f32> line;
line.start=box.MinEdge;
core::vector3df force_continuous_for_line=last_force_continuous*99999;
line.end=(line.start+force_continuous_for_line);
irr::newton::IntersectionPoint p=
p_node->world->getCollisionManager()->getCollisionFirstPoint(line);
//debug info
core::stringc message;
message+="line start ";
message+=(double)line.start.X;
message+=",";
message+=(double)line.start.Y;
message+=",";
message+=(double)line.start.Z;
message+=" line.end";
message+=(double)line.end.X;
message+=",";
message+=(double)line.end.Y;
message+=",";
message+=(double)line.end.Z;
message+=" point";
//end of debug info
if(p.body!=NULL) {
//debug infos
message+=(double)p.point.X;
message+=",";
message+=(double)p.point.Y;
message+=",";
message+=(double)p.point.Z;
//end of debug infos
irr::f32 distance=fabs(box.MinEdge.getDistanceFrom(p.point));
//a 29.40 dà ancora sgnali, a 29.45 non più
//if(distance>32.0f) {
if(distance>29.41f) {
irr::f32 mass=p_node->getMass();
irr::f32 deltaHeight=distance;
dFloat timestep;
dFloat timestepInv;
// Get the current world timestep
timestep = NewtonGetTimeStep(p_node->world->getNewtonWorld());
timestepInv = 1.0f / timestep;
// snap to floor only if the floor is lower than the character feet
//irr::f32 accelY = - ((deltaHeight * timestepInv + velocity.Y) /10);
//p_node->force_continuos.Y = mass * accelY;
NewtonBodyAddForce(p_node->body,&last_force_continuous.X);
return;
//p_node->force_continuos=last_force_continuous;
//debug infos
message+=" force continuous: ";
message+=(double)p_node->force_continuos.X;
message+=",";
message+=(double)p_node->force_continuos.Y;
message+=",";
message+=(double)p_node->force_continuos.Z;
//end of debug infos
hidden_device->getLogger()->log(message.c_str());
}
}//if(p.body!=NULL) {
irr::newton::Hidden::defBodyForceAndTorqueCallback(body);
p_node->force_continuos=last_force_continuous;
}//if(p_node->apply_force_if_not_air_borne)
*/
//END OF INTERPOLATION
//p_node->force_continuos=last_force_continuos;
irr::newton::ICharacterController* p_node=(irr::newton::ICharacterController*)NewtonBodyGetUserData(body);
irr::newton::Hidden::defBodyForceAndTorqueCallback(body);
//end of force and torque default
//center the mouse
if(p_node->center_mouse)
hidden_device->getCursorControl()->setPosition(0.5f,0.5f);
//for setting velocity
//CAN SET VELOCITY
if(p_node->can_set_velocity!=0){
float plus=
fabs(p_node->position_difference.X)+
fabs(p_node->position_difference.Y)+
fabs(p_node->position_difference.Z);
const float minimum_value=+0.00001f;
if(plus<=minimum_value) {
switch(p_node->can_set_velocity) {
case (1): p_node->can_set_velocity=2;break;
case (2): p_node->can_set_velocity=3;break;
case (3): p_node->can_set_velocity=4;break;
case (4): p_node->can_set_velocity=5;break;
case (5): p_node->can_set_velocity=6;break;
case (6): p_node->can_set_velocity=7;break;
case (7): p_node->can_set_velocity=8;break;
case (8): p_node->can_set_velocity=0;break;
}//switch
//can set force
switch(p_node->can_set_force) {
case(0): break;
case (1): p_node->can_set_force=2;break;
case (2): p_node->can_set_force=3;break;
case (3): p_node->can_set_force=4;break;
case (4): p_node->can_set_force=5;break;
case (5): p_node->can_set_force=6;break;
case (6): p_node->can_set_force=7;break;
case (7): p_node->can_set_force=8;break;
case (8): p_node->can_set_force=0;break;
}//switch
}//if(plus<0.00001f&&p_node->can_set_velocity!=ESV_CAN) {
//restore if move
else if(plus>minimum_value) {
p_node->can_set_velocity=1;
//force
if(p_node->can_set_force!=0)
p_node->can_set_force=1;
}//else if(plus>minimum_value) {
}// if(p_node->can_set_velocity!=0){
p_node->position_difference=core::vector3df(0,0,0);
//----------------------------------------------------------------------------
//-------------STAIR CLIMBING-------------------------------------------------
//----------------------------------------------------------------------------
core::vector3df body_pos=p_node->getNode()->getPosition();
body_pos.Y=0;
//avoid penetration
p_node->getWorld()->getUtils()->round(body_pos.X,1);
p_node->getWorld()->getUtils()->round(body_pos.Z,1);
//CHECK IF WE CAN DO THAT
static core::vector3df last_direction=core::vector3df();
static core::vector3df last_body_position = core::vector3df();
bool do_stair_climbing=true;
//check if last direction
if(last_direction != (p_node->getLastDirectionParameter()+body_pos))
last_direction = p_node->getLastDirectionParameter()+body_pos;
else do_stair_climbing=false;
//END OF CHECKING
if(p_node->getClimbStairForce()!=core::vector3df()&&do_stair_climbing) {
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
core::vector3df point_body;
//calculate AABB
core::aabbox3d<f32> box=p_node->calculateAABB();
core::vector3df minEdge = p_node->getPosition();
core::vector3df lastDirectionParameter=p_node->getLastDirectionParameter();
lastDirectionParameter.normalize();
lastDirectionParameter*=50;
//check ray cast point in body
core::line3d<f32> line_trought_body;
line_trought_body.start = line_trought_body.end = minEdge;
line_trought_body.start += lastDirectionParameter;
line_trought_body.end -= lastDirectionParameter;
newton::SIntersectionPoint i_point_body;
p_node->getWorld()->getCollisionManager()->getCollisionPoint(
p_node,
line_trought_body,
i_point_body);
//reduce point position to avoid penetration
//WORK CORECTLY, BUT IS THIS NECESARY?
line_trought_body.start*=IrrToNewton;
line_trought_body.end*=IrrToNewton;
i_point_body.parametric_value+=0.05f;
i_point_body.point = line_trought_body.start + i_point_body.parametric_value * (line_trought_body.end - line_trought_body.start);
i_point_body.point*=NewtonToIrr;
//set point and set y position as min edge
point_body = i_point_body.point;
point_body.Y = box.MinEdge.Y-5;
//DEBUG
/*
video::IVideoDriver* driver = p_node->getWorld()->getIrrlichtDevice()->getVideoDriver();
scene::ISceneNode* bill=p_node->getWorld()->getIrrlichtDevice()->getSceneManager()->addBillboardSceneNode();
bill->setPosition(point_body);
bill->setMaterialTexture(0,driver->getTexture("D:\\raffaele\\programmi\\phisic\\media\\wheel_texture.jpg"));
bill->setMaterialFlag(video::EMF_LIGHTING,false);
bill=p_node->getWorld()->getIrrlichtDevice()->getSceneManager()->addBillboardSceneNode();
bill->setPosition(line_trought_body.start);
bill->setMaterialFlag(video::EMF_LIGHTING,false);
bill=p_node->getWorld()->getIrrlichtDevice()->getSceneManager()->addBillboardSceneNode();
bill->setPosition(line_trought_body.end);
bill->setMaterialFlag(video::EMF_LIGHTING,false);
*/
//END OF DEBUG
//stair climbing
//make direction
lastDirectionParameter.normalize();
lastDirectionParameter*=13;
//build direction
core::line3d<f32> direction;
direction.start = direction.end = point_body;
direction.end += lastDirectionParameter;
newton::SIntersectionPoint raycast_1=
p_node->getWorld()->getCollisionManager()->getCollisionFirstPointEx(direction);
if(raycast_1.body!=NULL) {
//collide!! is a stair? or a wall?
//distance
irr::f32 distance_point1_body=raycast_1.point.getDistanceFrom(direction.start);
//up the direction
direction.start.Y+=p_node->stair_max_height;
direction.end.Y+=p_node->stair_max_height;
//second raycast
newton::SIntersectionPoint raycast_2=
p_node->getWorld()->getCollisionManager()->getCollisionFirstPointEx(direction);
irr::f32 distance_point2_body=raycast_2.point.getDistanceFrom(direction.start);
//conditional
if(raycast_2.body==NULL||
((raycast_2.body!=NULL)&&(distance_point1_body<distance_point2_body))
) {
//There is a stair!!! Make the body climb it!!!
core::vector3df vel = p_node->getVelocity();
//NEW CODE STAIR CLIMB
if(vel.Y < p_node->getClimbStairForce().Y)
vel.Y = p_node->getClimbStairForce().Y;
p_node->setVelocity(vel);
}//if(raycast_2.body==NULL) {
}//if(raycast_1.body!=NULL) {
}//if gravity force != 0,0,0
/*
//DON'T ERASE. SET GRAVITY ONLY IN CERTAIN CIRCUMSTANCE
if(p_node->getGravity()!=core::vector3df()) {
core::aabbox3d<f32> box=p_node->calculateAABB();
core::line3d<f32> line(box.MinEdge,box.MinEdge);
line.end.Y-=99999.9f;
newton::SIntersectionPoint i_point;
i_point=p_node->getWorld()->getCollisionManager()->getCollisionFirstPointEx(line);
if(i_point.body!=NULL) {
irr::f32 distance = fabs(line.start.getDistanceFrom(i_point.point));
if(distance >= p_node->stair_max_height) {
p_node->addForce(p_node->getGravity());
}
}
}//if gravity!=0,0,0
*/
//---------------------------------------------------------------
//--------CAMERA FPS SPECIFIC------------------------------------
//---------------------------------------------------------------
if(p_node->class_type.Type==ECT_CAMERA_FPS_BODY) {
newton::ICameraBodyFPS* cam_body=(newton::ICameraBodyFPS*)p_node;
//move and rotate
cam_body->world->getUtils()->updateCameraFPS(
cam_body,
cam_body->mouseSensitive,
cam_body->moveSpeed,
cam_body->isPaused?newton::SDirection():newton::SDirection(cam_body->up,cam_body->down,cam_body->left,cam_body->right),
cam_body->verticalMovement,
cam_body->onlyY,
cam_body->isPaused?false:true //stop if not moving. don't stop is it is in paused, else stop
);
//to unpause if time is elapsed
cam_body->updatePause();
}//camera fps
}
Code: Select all
if(p_node->getClimbStairForce()!=core::vector3df()&&do_stair_climbing) {
Code: Select all
newton::SIntersectionPoint point;//but is it relay a stair?? or is the char flying??
f32 dist = p_node->world->getUtils()->getDistanceFromFloor(p_node, point);
Code: Select all
if(dist <= p_node->stair_max_height) {//Make the body climb it!!!
Code: Select all
newton::SIntersectionPoint raycast_1=
p_node->getWorld()->getCollisionManager()->getCollisionFirstPointEx(direction);
if(raycast_1.body!=NULL) {
//collide!! is a stair? or a wall?
//distance
irr::f32 distance_point1_body=raycast_1.point.getDistanceFrom(direction.start);
[b] //up the direction
direction.start.Y+=p_node->stair_max_height;
direction.end.Y+=p_node->stair_max_height;[/b]
//second raycast
newton::SIntersectionPoint raycast_2=
p_node->getWorld()->getCollisionManager()->getCollisionFirstPointEx(direction);
if(raycast_2.body==NULL
Code: Select all
if(net_applied_force.Y >= 0) {
//climb the stair
}
yeah... thats right.. diasble stairclimbing is ugly... but... well.. i absoultly not understood, why stair detection went crazy while crouching... but.. if it is a irrlicht internal/CompilerBased problem i don´t know... well, i would have to use the looger class to test this... and this would mean to learn how to use^^ so many things to do..for crouching you would be need stair climbing when crouching, so i think the best solution would be solve stair detection when crouching, not deactive stair climbing when crouching. so i will compile it for dev-c++ and with irrlicht 1.3 to test it