This is the code. I hope you don't need the .X File, but if you have any interest, just ask.
The code which made the thing go wrong are marked with "////////////////////////////"
Code: Select all
class myAnimationEndCB : public IAnimationEndCallBack
{
void OnAnimationEnd (IAnimatedMeshSceneNode *node){
node->setLoopMode(true);
node->setFrameLoop(0,45);
}
};
player::player(IrrlichtDevice *device, ISceneNode *parent,ISceneManager *mangr,s32 id=0, const c8 *XFile=0)
{
smgr=mangr;
keys=0;
avatarMesh=0;
avatar=0;
status=0;
lastStatus=0; //para detectar cambios de estado, luego esto se hará con un FSM que reaccionara a las entradas de "keys"
rotAngle=0;
reloj=device->getTimer();
linearSpeed=8.0f;//incluir metodos para variar la velocidad lineal por segundo, de momento es fija a 5 metros por segundo
currentTime=reloj->getTime();
ITexture *NormalMap;
IGPUProgrammingServices *gpu;
u32 materialType;
shaderConstants *mySC=new shaderConstants();
presionado=false;
gravitySpeed=0;
if(XFile){
avatarMesh = (ISkinnedMesh*)smgr->getMesh(XFile);
avatarMesh->setInterpolationMode(EIM_LINEAR );
avatarMesh->convertMeshToTangents();
avatar= smgr->addAnimatedMeshSceneNode(avatarMesh);
avatar->setFrameLoop(0,45);
avatar->setID(id);
gpu=smgr->getVideoDriver()->getGPUProgrammingServices();
//amos a intentar meterle un shader molon...
/*
materialType=gpu->addHighLevelShaderMaterialFromFiles(
"./data/graphics/shaders/ShaderPhongLightV.hlsl",
"vs_main",
EVST_VS_2_0,
"./data/graphics/shaders/ShaderPhongLightP.hlsl",
"ps_main",
EPST_PS_2_0,
mySC,
EMT_SOLID,
0);
*/
NormalMap=smgr->getVideoDriver()->getTexture("./data/graphics/characters/uni-alpha/blueref.png");
avatar->getMaterial(0).MaterialType=EMT_REFLECTION_2_LAYER;
avatar->getMaterial(0).setTexture(1,NormalMap);
for(int i=0;i<avatar->getMaterialCount();i++){
avatar->getMaterial(i).setFlag(EMF_FOG_ENABLE ,true);
avatar->getMaterial(i).AmbientColor=SColor(255,128,128,128);
}
}
///////////////////////////////////////////////////////////////////here
avatar->setTransitionTime(0.25);
avatar->setJointMode(EJUOR_CONTROL);
/////////////////////////////////////////////////////////////////////////
}
void player::update(ISceneNodeAnimatorCollisionResponse *collider){
core::vector3df vectRot=core::vector3df(0,0,0);
core::triangle3df tri;
core::vector3df colPoint;
lastTime=currentTime;
currentTime=reloj->getTime();
myAnimationEndCB *myAnEndCB = new myAnimationEndCB();
lastStatus=status;
status=ESPERANDO;
vectRot=vector3df(0.0,0.0,0.0);
avRot=vector3df(0.0,0.0,0.0);
avatar->setAnimationEndCallback(myAnEndCB);
////////////////////////////////////////////////////////////////////Here!
avatar->animateJoints(true);
////////////////////////////////////////////////////////////////////
if(collider->isFalling()){ //&& (lastPos.Y-avatar->getPosition().Y)*(lastPos.Y-avatar->getPosition().Y)>0.001
if(lastStatus==SALTO)
avatar->setLoopMode(false);
}else{
avatar->setLoopMode(true);
}
lastPos=avatar->getPosition();
if((*keys)&31 && lastStatus!=ATAQUE && !presionado){
avRot=avatar->getPosition()-smgr->getActiveCamera()->getPosition();//rotacion con respecto a la camara
if((*keys)&1){
vectRot.Z=1;
status=CORRIENDO;
}
if((*keys)&4){
vectRot.X=1;
status=CORRIENDO;
}
if((*keys)&8){
vectRot.Z=-1;
status=CORRIENDO;
}
if((*keys)&2){
vectRot.X=-1;//o un multiplicador analógico de un mando idem
status=CORRIENDO;
}
if((*keys)&16 && !presionado){
vectRot.Y=1.0;
status=SALTO;
}
rotAngle=vectRot.getHorizontalAngle().Y;//esto es correcto, lo incorrecto es la inclinacion del personaje,
//pero con un mando analógico, es cuando deberia ser suave.
avRot.Y=0;
avRot.rotateXZBy(rotAngle,core::vector3df(0.0,0.0,0.0));
if(vectRot.X==0 && vectRot.Z==0){
avRot.X=0.0;
avRot.Z=0.0;
}
avRot=avRot.normalize();
avRot.Y+=vectRot.Y;
avatar->setPosition(avatar->getPosition()+ avRot*linearSpeed/1000*(currentTime-lastTime));
if(vectRot.X!=0 || vectRot.Z!=0){
//actualizamos solo si merece la pena ;)
Face = avatar->getPosition()-lastPos;
}
}
avatar->setRotation(core::vector3df(0, Face.getHorizontalAngle().Y, 0));
if((*keys)&32&&status!=ATAQUE && !presionado){
status=ATAQUE;
presionado=true;
avatar->setLoopMode(false);
}
if(avatar->getStartFrame()==0){
presionado=false;
}
if(lastStatus==ESPERANDO && status==ATAQUE){avatar->setFrameLoop(90,100);}
if(lastStatus==SALTO && status==ATAQUE){avatar->setFrameLoop(90,100);}
if(lastStatus==CORRIENDO && status==ATAQUE){avatar->setFrameLoop(90,100);}
if(lastStatus==ESPERANDO && status==CORRIENDO){avatar->setFrameLoop(55,75);}
if(lastStatus==SALTO && status==CORRIENDO){avatar->setFrameLoop(55,75);}
if(lastStatus==CORRIENDO && status==SALTO){avatar->setFrameLoop(80,85);}
if(lastStatus==ESPERANDO && status==SALTO){avatar->setFrameLoop(80,85);}
if(lastStatus!=ESPERANDO && status==ESPERANDO){avatar->setFrameLoop(0,45);}
//actualizamos el aspecto del personaje.
smgr->getSceneCollisionManager()->getCollisionPoint(core::line3df(avatar->getPosition(),avatar->getPosition()-vector3df(0,1,0)),
collider->getWorld(),
colPoint,
tri);
//ya puestos, podria dibujarse un circulito ahi abajo y ya tenemos sombras simples XD
}
I'm not too good documenting code, but i think it is pretty much understandable.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt