void Character::init(Portal* blue, Portal* orange){ takenEntity[2]= new Interface(blue, orange); Character::blue = blue; Character::orange = orange; //cout << pos << endl; std::vector<vector3> walls; std::vector<Floor*> floors; collision(&walls, &floors); //find active floor std::vector<Floor*>::iterator its = floors.begin(); Floor* below_floor=*its; GLfloat below_height = below_floor->get_height(pos); for(its++; its!=floors.end(); its++){ Floor* fl = *its; GLfloat floor_height = fl->get_height(pos); if(floor_height>=pos[1] && floor_height<=below_height){ below_floor=fl; below_height=floor_height; } } actual_floor=below_floor; }
void Character::movement(){ float interval = pe.idle()/100; vector3 tmp = dir; vector3 tmp2 = dir; vector3 tmp3 = side; std::vector<vector3> walls; std::vector<Floor*> floors; Portal* teleport_portal = collision(&walls, &floors); //teleporting if(teleport_portal!=NULL){ vector3 other_dir = teleport_portal->other_portal->getDir(); GLfloat rot_angle = asin(dir[0]*other_dir[2]-dir[2]*other_dir[0]); if(teleport_portal->getDir()[1]==0.0){ pos = teleport_portal->getPos()+teleport_portal->getDir()*1.5; pos[1]-=0.9; dir[0] = teleport_portal->getDir()[0]; dir[2] = teleport_portal->getDir()[2]; }else pos = teleport_portal->getPos()+teleport_portal->getDir()*2.5; dir = rotate_vector(dir, vector3(0.0, 1.0, 0.0), -rot_angle); dir.normalize(); if(moveBackward) dir = -dir; side = cross(-dir, up); side.normalize(); at = pos + dir; jump=true; v0 = vector3(0.0,0.0,0.0); t0 = glutGet(GLUT_ELAPSED_TIME); return; } //wall-collision response std::vector<vector3>::iterator it; for(it=walls.begin(); it!=walls.end(); it++){ vector3 collider = *it; //perpendicular of collider collider[0] = collider[0] + collider[2]; collider[2] = collider[0] - collider[2]; collider[0] = collider[0] - collider[2]; collider[2] = -collider[2]; collider[1] = 0; GLfloat t2l = tmp2.length(); GLfloat t3l = tmp3.length(); GLfloat cosangle1 = (tmp2[0]*collider[0]+tmp2[2]*collider[2])/(t2l); GLfloat sinangle1 = (tmp2[0]*collider[2]-tmp2[2]*collider[0])/(t2l); GLfloat cosangle2 = (tmp3[0]*collider[0]+tmp3[2]*collider[2])/(t3l); GLfloat sinangle2 = (tmp3[0]*collider[2]-tmp3[2]*collider[0])/(t3l); if((sinangle2<0.0 && moveRight) || (sinangle2>=0.0 && moveLeft)) tmp3 = collider*cosangle2; if((sinangle1>0.0 && moveForward) || (sinangle1<=0.0 && moveBackward)) tmp2 = collider*cosangle1; } tmp3[1]=0.0; tmp[1]=dir1; //find below floor std::vector<Floor*>::iterator its; Floor* below_floor; GLfloat below_height=-100.0; for(its=floors.begin(); its!=floors.end(); its++){ Floor* fl = *its; GLfloat floor_height = fl->get_height(pos); //cout << pos[1] << " " << floor_height << " " << below_height << endl; if(floor_height-1.0<=pos[1] && floor_height>=below_height && fl->getDir()[1]>0.0){ below_floor=fl; below_height=floor_height; } } //cout << "........." << endl; //jump reaction and landing if(jump){ pos = pe.getProjectileMotion(pos, v0, t0); if(pos[1]<=below_height){ jump=false; pos[1]=below_height; v0 = vector3(0.0,0.0,0.0); } at[1]=pos[1]+dir1; }else{ //floor-collision response //tmp2 = tmp2 - dot(tmp2,below_floor->getDir())*below_floor->getDir(); //vector projection //tmp3 = tmp3 - dot(tmp3,below_floor->getDir())*below_floor->getDir(); //vector projection //cout << actual_floor << " " << below_floor << endl; if(actual_floor != below_floor){ //falling situation //cout << "ok" << endl; actual_floor = below_floor; jump=true; t0 = glutGet(GLUT_ELAPSED_TIME); }else{ pos[1]=below_height; } } if(moveForward) pos += interval*tmp2; if(moveBackward) pos -= interval*tmp2; if(moveRight) pos -= interval*tmp3; if(moveLeft) pos += interval*tmp3; at = pos + tmp; //cout << collider[1] << endl; }