Point WalkNavigationTool::projectToFloor(const Point& p) { /* Project the given point onto the floor plane along the up direction: */ const Vector& normal=getFloorPlane().getNormal(); Scalar lambda=(getFloorPlane().getOffset()-p*normal)/(getUpDirection()*normal); return p+getUpDirection()*lambda; }
void WalkNavigationTool::initContext(GLContextData& contextData) const { if(factory->drawMovementCircles) { /* Create a new data item: */ DataItem* dataItem=new DataItem; contextData.addDataItem(this,dataItem); /* Create the movement circle display list: */ glNewList(dataItem->movementCircleListId,GL_COMPILE); /* Set up OpenGL state: */ glPushAttrib(GL_ENABLE_BIT|GL_LINE_BIT); glDisable(GL_LIGHTING); glLineWidth(1.0f); glColor(factory->movementCircleColor); /* Create a coordinate system for the floor plane: */ Vector y=factory->centerViewDirection; Vector x=y^getFloorPlane().getNormal(); x.normalize(); /* Draw the inner circle: */ glBegin(GL_LINE_LOOP); for(int i=0; i<64; ++i) { Scalar angle=Scalar(2)*Math::Constants<Scalar>::pi*Scalar(i)/Scalar(64); glVertex(Point::origin-x*(Math::sin(angle)*factory->innerRadius)+y*(Math::cos(angle)*factory->innerRadius)); } glEnd(); /* Draw the outer circle: */ glBegin(GL_LINE_LOOP); for(int i=0; i<64; ++i) { Scalar angle=Scalar(2)*Math::Constants<Scalar>::pi*Scalar(i)/Scalar(64); glVertex(Point::origin-x*(Math::sin(angle)*factory->outerRadius)+y*(Math::cos(angle)*factory->outerRadius)); } glEnd(); /* Draw the inner angle: */ glBegin(GL_LINE_STRIP); glVertex(Point::origin-x*(Math::sin(factory->innerAngle)*factory->innerRadius)+y*(Math::cos(factory->innerAngle)*factory->innerRadius)); glVertex(Point::origin); glVertex(Point::origin-x*(Math::sin(-factory->innerAngle)*factory->innerRadius)+y*(Math::cos(-factory->innerAngle)*factory->innerRadius)); glEnd(); /* Draw the outer angle: */ glBegin(GL_LINE_STRIP); glVertex(Point::origin-x*(Math::sin(factory->outerAngle)*factory->outerRadius)+y*(Math::cos(factory->outerAngle)*factory->outerRadius)); glVertex(Point::origin); glVertex(Point::origin-x*(Math::sin(-factory->outerAngle)*factory->outerRadius)+y*(Math::cos(-factory->outerAngle)*factory->outerRadius)); glEnd(); /* Reset OpenGL state: */ glPopAttrib(); glEndList(); } }
WalkNavigationToolFactory::WalkNavigationToolFactory(ToolManager& toolManager) :ToolFactory("WalkNavigationTool",toolManager), floorPlane(getFloorPlane()), centerOnActivation(false), centerPoint(getDisplayCenter()), moveSpeed(getDisplaySize()), innerRadius(getDisplaySize()*Scalar(0.5)),outerRadius(getDisplaySize()*Scalar(0.75)), centerViewDirection(getForwardDirection()), rotateSpeed(Math::rad(Scalar(120))), innerAngle(Math::rad(Scalar(30))),outerAngle(Math::rad(Scalar(120))), drawMovementCircles(true), movementCircleColor(0.0f,1.0f,0.0f) { /* Initialize tool layout: */ layout.setNumDevices(1); layout.setNumButtons(0,1); /* Insert class into class hierarchy: */ ToolFactory* navigationToolFactory=toolManager.loadClass("NavigationTool"); navigationToolFactory->addChildClass(this); addParentClass(navigationToolFactory); /* Load class settings: */ Misc::ConfigurationFileSection cfs=toolManager.getToolClassSection(getClassName()); floorPlane=cfs.retrieveValue<Plane>("./floorPlane",floorPlane); floorPlane.normalize(); centerOnActivation=cfs.retrieveValue<bool>("./centerOnActivation",centerOnActivation); centerPoint=cfs.retrieveValue<Point>("./centerPoint",centerPoint); centerPoint=floorPlane.project(centerPoint); moveSpeed=cfs.retrieveValue<Scalar>("./moveSpeed",moveSpeed); innerRadius=cfs.retrieveValue<Scalar>("./innerRadius",innerRadius); outerRadius=cfs.retrieveValue<Scalar>("./outerRadius",outerRadius); centerViewDirection=cfs.retrieveValue<Vector>("./centerViewDirection",centerViewDirection); centerViewDirection=floorPlane.project(centerViewDirection); centerViewDirection.normalize(); rotateSpeed=Math::rad(cfs.retrieveValue<Scalar>("./rotateSpeed",Math::deg(rotateSpeed))); innerAngle=Math::rad(cfs.retrieveValue<Scalar>("./innerAngle",Math::deg(innerAngle))); outerAngle=Math::rad(cfs.retrieveValue<Scalar>("./outerAngle",Math::deg(outerAngle))); drawMovementCircles=cfs.retrieveValue<bool>("./drawMovementCircles",drawMovementCircles); movementCircleColor=cfs.retrieveValue<Color>("./movementCircleColor",movementCircleColor); /* Set tool class' factory pointer: */ WalkNavigationTool::factory=this; }