int tux_translate( ClientData cd, Tcl_Interp *ip, int argc, const char *argv[] ) { const char *errmsg; const char *nodename; scalar_t vec[3]; if (3 != argc) { Tcl_AppendResult(ip, argv[0], ": invalid number of arguments\n", "Usage: ", argv[0], " <node> { <x> <y> <z> }", (char *)0 ); return TCL_ERROR; } /* obtain the nodename */ nodename = argv[1]; /* obtain the translation vector */ if (TCL_OK != get_tcl_tuple(ip,argv[2],vec,3)) { Tcl_AppendResult(ip, argv[0], ": invalid translation vector", (char *)0 ); return TCL_ERROR; } errmsg = translate_scene_node(nodename,make_vector_from_array(vec)); /* report error, if any */ if (errmsg) { Tcl_AppendResult(ip, argv[0], ": ", errmsg, (char *)0 ); return TCL_ERROR; } return TCL_OK; }
void set_tux_pos(Player& plyr, ppogl::Vec3d newPos) { const ppogl::Vec2d& playDim = Course::getPlayDimensions(); const ppogl::Vec2d& courseDim = Course::getDimensions(); const float boundaryWidth = ( courseDim.x() - playDim.x() ) / 2; if(newPos.x() < boundaryWidth){ newPos.x() = boundaryWidth; }else if(newPos.x() > courseDim.x() - boundaryWidth){ newPos.x() = courseDim.x() - boundaryWidth; } if(newPos.z()>0){ newPos.z() = 0; }else if(-newPos.z() >= playDim.y()){ newPos.z() = -playDim.y(); GameMode::setMode(GameMode::GAME_OVER); } plyr.pos = newPos; const float disp_y = newPos.y() + TUX_Y_CORRECTION_ON_STOMACH; const std::string& tuxRoot = tux[plyr.num].getRootNode(); reset_scene_node( tuxRoot ); translate_scene_node( tuxRoot, ppogl::Vec3d( newPos.x(), disp_y, newPos.z() ) ); }
static bool check_model_collisions(Player& plyr, const ppogl::Vec3d& pos, ppogl::Vec3d *tree_loc, float *tree_diam) { if(GameConfig::disableCollisionDetection){ return false; } if(modelLocs.empty()){ //no models? what a boring course... return false; } pp::Matrix mat; bool hit = false; ppogl::Vec3d distvec; float squared_dist; /* These variables are used to cache collision detection results */ static bool last_collision = false; static ppogl::Vec3d last_collision_tree_loc( -999, -999, -999 ); static double last_collision_tree_diam = 0; static ppogl::Vec3d last_collision_pos( -999, -999, -999 ); /* If we haven't moved very much since the last call, we re-use the results of the last call (significant speed-up) */ ppogl::Vec3d dist_vec = pos - last_collision_pos; if ( dist_vec.length2() < COLLISION_TOLERANCE ) { if ( last_collision ) { if ( tree_loc != NULL ) { *tree_loc = last_collision_tree_loc; } if ( tree_diam != NULL ) { *tree_diam = last_collision_tree_diam; } return true; } else { return false; } } ppogl::RefPtr<ModelType> model_type = (*modelLocs.begin()).getType(); ppogl::Polyhedron *ph = model_type->ph; float diam=0.0; float height; ppogl::Vec3d loc; std::list<Model>::iterator it; for(it=modelLocs.begin();it!=modelLocs.end();it++) { diam = (*it).getDiameter(); height = (*it).getHeight(); loc = (*it).getPosition(); distvec = ppogl::Vec3d( loc.x() - pos.x(), 0.0, loc.z() - pos.z() ); /* check distance from tree; .6 is the radius of a bounding sphere around tux (approximate) */ squared_dist = ( diam/2. + 0.6 ); squared_dist *= squared_dist; if ( distvec.length2() > squared_dist ) { continue; } /* have to look at polyhedron - switch to correct one if necessary */ if ( model_type != ((*it).getType()) ) { model_type = (*it).getType(); ph = model_type->ph; } ppogl::Polyhedron ph2(*ph); mat.makeScaling( diam, diam, diam ); trans_polyhedron( mat, ph2 ); mat.makeTranslation( loc.x(), loc.y(), loc.z() ); trans_polyhedron( mat, ph2 ); const std::string& tux_root = tux[plyr.num].getRootNode(); reset_scene_node( tux_root ); translate_scene_node( tux_root, ppogl::Vec3d( pos.x(), pos.y(), pos.z() ) ); hit = collide( tux_root, ph2 ); if ( hit == true ) { if ( tree_loc != NULL ) { *tree_loc = loc; } if ( tree_diam != NULL ) { *tree_diam = diam; } break; } } last_collision_tree_loc = loc; last_collision_tree_diam = diam; last_collision_pos = pos; if(hit){ last_collision = true; // Record collision in player data so that health can be adjusted plyr.collision = true; }else{ last_collision = false; } return hit; }