/// <summary> /// /// </summary> public override void Update() { //Calculate the direction the impostor batches should be facing Vector3 camPos = mGeom.ConvertToLocal(mGeom.Camera.DerivedPosition); //Update all batches float distX = camPos.x - mCenter.x; float distZ = camPos.z - mCenter.z; float distY = camPos.y - mCenter.y; float distRelZ = MogreLibMath.Utility.Sqrt(distX * distX + distZ * distZ); Radian pitch = MogreLibMath.Utility.ATan2(distY, distZ); Radian yaw; if (distRelZ > mGeom.PageSize * 3) { yaw = MogreLibMath.Utility.ATan2(distY, distZ); } else { Vector3 dir = mGeom.ConvertToLocal(mGeom.Camera.DerivedDirection); yaw = MogreLibMath.Utility.ATan2(-distX, -distZ); } foreach (ImpostorBatch batch in mImpostorBatches.Values) { batch.SetAngle((float)pitch.InDegrees, (float)yaw.InDegrees); } }
/// <summary> /// /// </summary> /// <param name="entity"></param> /// <param name="position"></param> /// <param name="yaw"></param> /// <param name="scale"></param> /// <param name="userData"></param> public void AddTree(Entity entity, Vector3 position, Degree yaw, float scale, object userData) { //First convert the coordinate to PagedGeometry's local system Vector3 pos = mGeom.ConvertToLocal(position); //If the tree is slightly out of bounds (due to imprecise coordinate conversion), fix it if (pos.x < mActualBounds.Left) { pos.x = mActualBounds.Left; } else if (pos.x > mActualBounds.Right) { pos.x = mActualBounds.Right; } if (pos.z < mActualBounds.Top) { pos.z = mActualBounds.Top; } else if (pos.z > mActualBounds.Bottom) { pos.z = mActualBounds.Bottom; } float x = pos.x; float z = pos.z; //Check that the tree is within bounds (DEBUG) float smallVal = 0.01f; if (pos.x < mActualBounds.Left - smallVal || pos.x > mActualBounds.Right + smallVal || pos.z < mActualBounds.Top - smallVal || pos.z > mActualBounds.Bottom + smallVal) { throw new Exception("Tree position is out of bounds"); } if (scale < mMinimumScale || scale > mMaximumScale) { throw new Exception("Tree scale out of range"); } //Find the appropriate page grid for the entity List <List <TreeDef> > pageGrid = null; if (!mPageGridList.TryGetValue(entity, out pageGrid)) { //If it does not exist, create a new page grid pageGrid = new List <List <TreeDef> >(); for (int i = 0; i < (mPageGridX * mPageGridZ); i++) { pageGrid.Add(new List <TreeDef>()); } //Register the new page grid in the pageGridList for later retrieval mPageGridList.Add(entity, pageGrid); } //Calculate the gridbounds-relative position of the tree float xrel = x - mGridBounds.Left; float zrel = z - mGridBounds.Top; //Get the appropriate grid element based on the new tree's position int pageX = (int)System.Math.Floor(xrel / mPageSize); int pageZ = (int)System.Math.Floor(zrel / mPageSize); List <TreeDef> treeList = GetGridPage(pageGrid, pageX, pageZ); //Create the new tree TreeDef tree = new TreeDef(); tree.XPos = (short)(65535 * (xrel - (pageX * mPageSize)) / mPageSize); tree.ZPos = (short)(65535 * (zrel - (pageZ * mPageSize)) / mPageSize); tree.Rotation = (byte)(255 * ((Real)yaw / 360.0f)); tree.Scale = (byte)(255 * ((scale - mMinimumScale) / mMaximumScale)); tree.UserData = userData; //Add it to the tree list treeList.Add(tree); //Rebuild geometry if necessary mGeom.ReloadGeometryPage(new Vector3(x, 0, z)); }