/// <summary>Calculates a camera position which will show the complet object.</summary> /// <param name="nif_obj">an object handle from NIFAPI</param> /// <param name="pos">which side will be viewed</param> /// <remarks>This is surely just the mathematical view. /// It's still possible that the object is shown from top if you choose "Front". /// ! BUG ! distance isn't always correct /// </remarks> public void targetObject(IntPtr nif_obj, e_viewPosition pos) { if (nif_obj == IntPtr.Zero) return; float x1, y1, z1, x2, y2, z2; x1 = y1 = z1 = x2 = y2 = z2 = 0; // just to keep compiler happy bool res = NIF.NIFAPI.GetBoundingBox(nif_obj, ref x1, ref y1, ref z1, ref x2, ref y2, ref z2); if (!res) return; Reset(); moveGlobal((x1+ x2)/2.0f, (y1+ y2)/2.0f, (z1+ z2)/2.0f); float distancemin = 50; // atleast near-clipping plane must be reached float distanceX = ( x2 - x1 ); float distanceY = ( y2 - y1 ); float distanceZ = ( z2 - z1 ); distanceX = (distanceX/2)/ (float) System.Math.Tan(45/2 * 3.14 / 180); distanceY = (distanceY/2)/ (float) System.Math.Tan(45/2 * 3.14 / 180); distanceZ = (distanceZ/2)/ (float) System.Math.Tan(45/2 * 3.14 / 180); distanceX = System.Math.Max(distancemin,distanceX); distanceY = System.Math.Max(distancemin,distanceY); distanceZ = System.Math.Max(distancemin,distanceZ); switch (pos) { case e_viewPosition.Top: moveLocal(0,0,-System.Math.Max(distanceX,distanceY)); break; case e_viewPosition.Front: rotateLocal(-90.0f,0.0f,0.0f,1.0f); rotateLocal(-90.0f,1.0f,0.0f,0.0f); moveLocal(0,0,-System.Math.Max(distanceY,distanceZ)); break; case e_viewPosition.Below: rotateLocal(180.0f,1.0f,0.0f,0.0f); moveLocal(0,0,-System.Math.Max(distanceX,distanceY)); break; case e_viewPosition.Back: rotateLocal(90.0f,0.0f,0.0f,1.0f); rotateLocal(-90.0f,1.0f,0.0f,0.0f); moveLocal(0,0,-System.Math.Max(distanceY,distanceZ)); break; case e_viewPosition.Right: rotateLocal(-90.0f,1.0f,0.0f,0.0f); moveLocal(0,0,-System.Math.Max(distanceX,distanceY)); break; case e_viewPosition.Left: rotateLocal(90.0f,1.0f,0.0f,0.0f); rotateLocal(180.0f,0.0f,0.0f,1.0f); moveLocal(0,0,-System.Math.Max(distanceX,distanceY)); break; } }
/// <summary>Calculates a camera position which will show the complet object.</summary> /// <param name="nif_obj">an object handle from NIFAPI</param> /// <param name="pos">which side will be viewed</param> /// <remarks>This is surely just the mathematical view. /// It's still possible that the object is shown from top if you choose "Front". /// ! BUG ! distance isn't always correct /// </remarks> public void targetObject(IntPtr nif_obj, e_viewPosition pos) { if (nif_obj == IntPtr.Zero) { return; } float x1, y1, z1, x2, y2, z2; x1 = y1 = z1 = x2 = y2 = z2 = 0; // just to keep compiler happy bool res = NIF.NIFAPI.GetBoundingBox(nif_obj, ref x1, ref y1, ref z1, ref x2, ref y2, ref z2); if (!res) { return; } Reset(); moveGlobal((x1 + x2) / 2.0f, (y1 + y2) / 2.0f, (z1 + z2) / 2.0f); float distancemin = 50; // atleast near-clipping plane must be reached float distanceX = (x2 - x1); float distanceY = (y2 - y1); float distanceZ = (z2 - z1); distanceX = (distanceX / 2) / (float)System.Math.Tan(45 / 2 * 3.14 / 180); distanceY = (distanceY / 2) / (float)System.Math.Tan(45 / 2 * 3.14 / 180); distanceZ = (distanceZ / 2) / (float)System.Math.Tan(45 / 2 * 3.14 / 180); distanceX = System.Math.Max(distancemin, distanceX); distanceY = System.Math.Max(distancemin, distanceY); distanceZ = System.Math.Max(distancemin, distanceZ); switch (pos) { case e_viewPosition.Top: moveLocal(0, 0, -System.Math.Max(distanceX, distanceY)); break; case e_viewPosition.Front: rotateLocal(-90.0f, 0.0f, 0.0f, 1.0f); rotateLocal(-90.0f, 1.0f, 0.0f, 0.0f); moveLocal(0, 0, -System.Math.Max(distanceY, distanceZ)); break; case e_viewPosition.Below: rotateLocal(180.0f, 1.0f, 0.0f, 0.0f); moveLocal(0, 0, -System.Math.Max(distanceX, distanceY)); break; case e_viewPosition.Back: rotateLocal(90.0f, 0.0f, 0.0f, 1.0f); rotateLocal(-90.0f, 1.0f, 0.0f, 0.0f); moveLocal(0, 0, -System.Math.Max(distanceY, distanceZ)); break; case e_viewPosition.Right: rotateLocal(-90.0f, 1.0f, 0.0f, 0.0f); moveLocal(0, 0, -System.Math.Max(distanceX, distanceY)); break; case e_viewPosition.Left: rotateLocal(90.0f, 1.0f, 0.0f, 0.0f); rotateLocal(180.0f, 0.0f, 0.0f, 1.0f); moveLocal(0, 0, -System.Math.Max(distanceX, distanceY)); break; } }