public cVector3 direction(cCritter pa, cCritter pb) { cVector3 dir = pb.Position - pa.Position; dir.normalize(); return(dir); }
public void setViewpoint(cVector3 toViewer, cVector3 lookatPoint, bool trytoseewholeworld = true) { //First do some default setup stuff cVector3 toviewer = new cVector3(); toviewer.copy(toViewer); cVector3 lookatpoint = new cVector3(); lookatpoint.copy(lookatPoint); _fieldofviewangle = cCritterViewer.STARTFIELDOFVIEWANGLE; Speed = 0.0f; _attitude = new cMatrix3(new cVector3(0.0f, 0.0f, -1.0f), new cVector3(-1.0f, 0.0f, 0.0f), new cVector3(0.0f, 1.0f, 0.0f), new cVector3(0.0f, 0.0f, 0.0f)); /* To get a reasonable default orientation, we arrange the viewer axes so that: * viewer x axis = world -z axis, viewer y axis = world -x axis, viewer z axis = world y axis. * We pick this orientation so that if the viewer moves "forward" (along its tangent vector) * it moves towards the world. (We correct the mismatch between the coordinate systems in the * cCritterViewer.loadViewMatrix method, which has a long comment about this.) * Note that we will adjust _position (fourth column) later in this call * with a moveTo, also we may rotate the _attitude a bit. */ if (!_perspective) //Ortho view, simply move up. { _proportionofworldtoshow = 1.0f; //Show all of a flat world. moveTo(lookatpoint + (new cVector3(0.0f, 0.0f, 1.0f)) * cCritterViewer.ORTHOZOFFSET); // Get above the world _maxspeed = _maxspeedstandard = 0.5f * cCritterViewer.ORTHOZOFFSET; //Mimic perspective case. } else //_perspective { if (toviewer.IsPracticallyZero) //Not usable, so pick a real direction. { toviewer.copy(new cVector3(0.0f, 0.0f, 1.0f)); //Default is straight up. } if (trytoseewholeworld) /* Treat toviewer as a direction, and back off in that direction * enough to see the whole world */ { toviewer.normalize(); //Make it a unit vector. _proportionofworldtoshow = cCritterViewer.PROPORTIONOFWORLDTOSHOW; //Trying to show all of a world when flying around it, often leaves too big a space around it. float furthestcornerdistance = Game.Border.maxDistanceToCorner(lookatpoint); float tanangle = (float)Math.Tan(_fieldofviewangle / 2.0f); /* We work with half the fov in this calculation, * the tanangle will be the ratio of visible distance to distance above the world, * that is, tanangle = dr/dz, where * Our dr is _proportionofworldtoshow * furthestcornerdistance, and * our dz is the unknown seeallz height we need to back off to. * Swap tangangle and dz to get the next formula. */ float seeallz = _proportionofworldtoshow * furthestcornerdistance / tanangle; moveTo(lookatpoint + toviewer * seeallz); } else /*Not trytoseewholeworld. In this case we don't normalize toviewer, instead * we treat it as a displacment from the lookatpoint. */ { moveTo(lookatpoint + toviewer); } lookAt(lookatpoint); _maxspeed = _maxspeedstandard = 0.5f * (Position - lookatpoint).Magnitude; /* Define the speed like this so it typically takes two seconds (1/0.5) * to fly in to lookatpoint. */ _lastgoodplayeroffset = Position - Game.Player.Position; } }