static void DrawSlidingLine(Vector3D startPosition, Vector3D endPosition, Color color1, Color color2) { float pieceLength = 0.1f; float lineLength = Vector3.Distance(startPosition, endPosition); Vector3D lineDir = Vector3D.Normalize(endPosition - startPosition); Vector3D delta = lineDir * pieceLength; Color currentColor = color1; Vector3D min = Vector3D.Min(startPosition, endPosition); Vector3D max = Vector3D.Max(startPosition, endPosition); float startOffset = SlidingOffset - (pieceLength * 2.0f) * ((int)(SlidingOffset / (pieceLength * 2.0f))) - 2 * pieceLength; Vector3D currentPos = startPosition + startOffset * lineDir; float actualLength = 0; while (actualLength < lineLength) { MyRenderProxy.DebugDrawLine3D(Vector3D.Clamp(currentPos, min, max), Vector3D.Clamp(currentPos + delta, min, max), currentColor, currentColor, false); if (currentColor == color1) { currentColor = color2; } else { currentColor = color1; } actualLength += pieceLength; currentPos += delta; } //MyRenderProxy.DebugDrawLine3D(startPosition, endPosition, color1, color2, false); }
/// <summary> /// Creates the smallest BoundingBox that will contain a group of points. /// </summary> /// <param name="points">A list of points the BoundingBox should contain.</param> public static BoundingBoxD CreateFromPoints(IEnumerable <Vector3D> points) { if (points == null) { throw new ArgumentNullException(); } bool flag = false; Vector3D result1 = new Vector3D(double.MaxValue); Vector3D result2 = new Vector3D(double.MinValue); foreach (Vector3D vector3 in points) { Vector3D vec3 = vector3; Vector3D.Min(ref result1, ref vec3, out result1); Vector3D.Max(ref result2, ref vec3, out result2); flag = true; } if (!flag) { throw new ArgumentException(); } else { return(new BoundingBoxD(result1, result2)); } }
static public OrientedBoundingBoxD GetBoundingBox(IMyCubeGrid entity) { var min = new Vector3D(int.MaxValue, int.MaxValue, int.MaxValue); var max = new Vector3D(int.MinValue, int.MinValue, int.MinValue); float multiplier = 2.5f; if (entity.GridSizeEnum == MyCubeSize.Small) { multiplier = 0.5f; } List <IMySlimBlock> blocks = new List <IMySlimBlock>(); entity.GetBlocks(blocks, null); foreach (IMySlimBlock block in blocks) { //Vector3 pos = Entity.GetBlockEntityPosition(block); min = Vector3D.Min(block.Position * multiplier, min); max = Vector3D.Max(block.Position * multiplier, max); } Vector3D size = max - min; BoundingBoxD bb = new BoundingBoxD(new Vector3D(0, 0, 0), size).Translate(entity.GetPosition() - (size / 2)); return(new OrientedBoundingBoxD(bb.Center, bb.HalfExtents, Quaternion.CreateFromRotationMatrix(entity.WorldMatrix.GetOrientation()))); }
public void SetAddVoxelContents(byte[] contents, ref BoundingBoxD bounding) { unchecked { // for QUANTIZATION_BITS == 8 we can just do System.Buffer.BlockCopy Array.Clear(this._packed, 0, this._packed.Length); for (int bitadr = 0, adr = 0; bitadr < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_TOTAL * QuantizationBits; bitadr += QuantizationBits, adr++) { var byteadr = bitadr >> 3; var c = ((uint)contents[adr] >> ThrowawayBits) << (bitadr & 7); if (c > 0) { // Find the bounding region for content. var x = adr / XStep; var y = (adr % XStep) / YStep; var z = (adr % XStep) % YStep; bounding.Min = Vector3D.Min(bounding.Min, new Vector3D(x, y, z)); bounding.Max = Vector3D.Max(bounding.Max, new Vector3D(x, y, z)); } this._packed[byteadr] |= (byte)c; this._packed[byteadr + 1] |= (byte)(c >> 8); // this needs to be done only for QUANTIZATION_BITS == 1,2,4,8 } } }
public void Advance() { if (_rotationLookVelocity == 0 && _rotationVelocity == 0 && _forwardVelocity == 0 && _rightVelocity == 0) { _timeLastUpdate = DateTime.Now; return; } DateTime now = DateTime.Now; TimeSpan span = now - _timeLastUpdate; float seconds = Math.Min(span.Milliseconds / 1000.0f, 0.5f) * 20; _timeLastUpdate = now; Vector3D localUp = this.World.LocalUpAxis; Vector3D localRight = this.World.LocalRightAxis; Vector3D localForward = this.World.LocalForwardAxis; // updating rotations are easy... _rotationBody += seconds * (_rotationVelocity * 30); _rotationLook = Math2.Clamp(_rotationLook + seconds * _rotationLookVelocity * 30, -1.4f, 1.4f); Matrix3D xfrm = Matrix3D.FromRotation(localUp, _rotationBody); Vector3D localVelocity = seconds * _forwardVelocity * localForward * 35 + seconds * _rightVelocity * localRight * 35; Vector3D absoluteVelocity = xfrm * localVelocity; Vector3D absoluteUp = xfrm * this.World.LocalUpAxis; Vector3D absoluteRight = xfrm * this.World.LocalRightAxis; Vector3D absoluteForward = xfrm * this.World.LocalForwardAxis; //Debug.WriteLine( "Velocity: " + velocityBody ); //Debug.WriteLine( "TimeStep Velocity: " + incrementalMovement ); //Vector3D extentCenter = xfrm * ( localForward * _bodyRadius ); //Vector3D extentTop = localUp * _bodyRadius; //Vector3D extentBottom = - localUp * ( _bodyHeight - _liftSize ); //Debug.WriteLine( "Old Position: " + _translationBody ); if (absoluteVelocity.GetMagnitude() > 0) { Vector3D moveDirection = absoluteVelocity.GetUnit(); Vector3D centerDelta = SmartStep(_translationBody, moveDirection, _bodyRadius, absoluteVelocity.GetMagnitude()); //+ extentCenter, _translationBody + extentCenter + absoluteVelocity ) - ( _translationBody + extentCenter ) - forwardStep; Vector3D topDelta = SmartStep(_translationBody + absoluteUp * _bodyRadius, moveDirection, _bodyRadius, absoluteVelocity.GetMagnitude()); //MoveTo( _translationBody + extentTop, _translationBody + extentTop + absoluteVelocity ) - ( _translationBody + extentTop ) - forwardStep; Vector3D bottomDelta = SmartStep(_translationBody - absoluteUp * (_bodyHeight - _liftSize), moveDirection, _bodyRadius, absoluteVelocity.GetMagnitude()); // MoveTo( _translationBody + extentBottom, _translationBody + extentBottom + absoluteVelocity ) - ( _translationBody + extentBottom ) - forwardStep; _translationBody += Vector3D.Min(Vector3D.Min(centerDelta, topDelta), bottomDelta); } _translationBody += SmartStep(_translationBody, absoluteRight, _bodyRadius, 0); _translationBody += SmartStep(_translationBody, -absoluteRight, _bodyRadius, 0); _translationBody += SmartStep(_translationBody, -absoluteUp, _bodyHeight, _liftSize); }
/// <summary> /// Constructs a <see cref="SlimMath.BoundingBox"/> that is as large as the total combined area of the two specified boxes. /// </summary> /// <param name="value1">The first box to merge.</param> /// <param name="value2">The second box to merge.</param> /// <returns>The newly constructed bounding box.</returns> public static BoundingBox Merge(BoundingBox value1, BoundingBox value2) { BoundingBox box; Vector3D.Min(ref value1.Minimum, ref value2.Minimum, out box.Minimum); Vector3D.Max(ref value1.Maximum, ref value2.Maximum, out box.Maximum); return(box); }
public static BoundingBoxD CreateMerged(BoundingBoxD original, BoundingBoxD additional) { BoundingBoxD xd; Vector3D.Min(ref original.Min, ref additional.Min, out xd.Min); Vector3D.Max(ref original.Max, ref additional.Max, out xd.Max); return(xd); }
public void Min() { Vector3D v1 = new Vector3D(1.0, 2.0, 2.5); Vector3D v2 = new Vector3D(-1.0, 2.0, 3.0); Vector3D min = Vector3D.Min(v1, v2); Assert.AreEqual(new Vector3D(-1.0, 2.0, 2.5), min); }
public static BoundingBoxD TransformBoundingBox(BoundingBoxD box, MatrixD matrix) { Vector3D a, b; Vector3D.Transform(ref box.Min, ref matrix, out a); Vector3D.Transform(ref box.Max, ref matrix, out b); return(new BoundingBoxD(Vector3D.Min(a, b), Vector3D.Max(a, b))); }
public static (double Size, Vector3D Center) GetBound(IEnumerable <Vector3D> positions) { var minPos = positions.Aggregate(Vector3D.MaxValue, (s, n) => Vector3D.Min(s, n)); var maxPos = positions.Aggregate(Vector3D.MinValue, (s, n) => Vector3D.Max(s, n)); var size = Vector3D.Distance(minPos, maxPos); var center = (minPos + maxPos) / 2; return(size, center); }
public MyBBSetSampler(Vector3D min, Vector3D max) { Vector3D newMax = Vector3D.Max(min, max); Vector3D newMin = Vector3D.Min(min, max); m_bBox = new BoundingBoxD(newMin, newMax); m_sampler = new IntervalSampler(newMin.X, newMax.X, (newMax.Y - newMin.Y) * (newMax.Z - newMin.Z), Base6Directions.Axis.LeftRight); }
public static void CreateMerged(ref BoundingBoxD original, ref BoundingBoxD additional, out BoundingBoxD result) { Vector3D vectord; Vector3D vectord2; Vector3D.Min(ref original.Min, ref additional.Min, out vectord); Vector3D.Max(ref original.Max, ref additional.Max, out vectord2); result.Min = vectord; result.Max = vectord2; }
public void Vector3MinTest() { Vector3D <float> a = new Vector3D <float>(-1.0f, 4.0f, -3.0f); Vector3D <float> b = new Vector3D <float>(2.0f, 1.0f, -1.0f); Vector3D <float> expected = new Vector3D <float>(-1.0f, 1.0f, -3.0f); Vector3D <float> actual; actual = Vector3D.Min(a, b); Assert.True(MathHelper.Equal(expected, actual), "Vector3D<float>f.Min did not return the expected value."); }
public static Vector3D MinCoord(TriMesh mesh) { Vector3D minCoord = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue); for (int i = 0; i < mesh.Vertices.Count; i++) { Vector3D v = mesh.Vertices[i].Traits.Position; minCoord = Vector3D.Min(minCoord, v); } return(minCoord); }
/// <summary> /// Creates the smallest BoundingBox that contains the two specified BoundingBox instances. /// </summary> /// <param name="original">One of the BoundingBox instances to contain.</param><param name="additional">One of the BoundingBox instances to contain.</param><param name="result">[OutAttribute] The created BoundingBox.</param> public static void CreateMerged(ref BoundingBoxD original, ref BoundingBoxD additional, out BoundingBoxD result) { Vector3D result1; Vector3D.Min(ref original.Min, ref additional.Min, out result1); Vector3D result2; Vector3D.Max(ref original.Max, ref additional.Max, out result2); result.Min = result1; result.Max = result2; }
public Vector3D MinCoord() { Vector3D minCoord = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue); for (int i = 0, j = 0; i < vertexCount; i++, j += 3) { Vector3D v = new Vector3D(vertexPos, j); minCoord = Vector3D.Min(minCoord, v); } return(minCoord); }
private bool TickThrusters(MotionState state, MotionTarget target) { Vector3D currentVelocity = state.VelocityLocal; Vector3D currentPosition = Vector3D.Transform(state.Position, state.WorldMatrixInverse); Vector3D currentGravity = state.GravityLocal; Vector3D targetSpeed = target.Speed; Vector3D targetPosition = Vector3D.Transform(target.Position ?? (state.Position + (targetSpeed + currentVelocity) * DELTA * .66), state.WorldMatrixInverse); Vector3D speedDifference = targetSpeed - currentVelocity; Vector3D positionDifference = targetPosition - currentPosition; if (speedDifference.LengthSquared() < velocityPrecision && positionDifference.LengthSquared() < positionPrecision) { ClearThrustersOverride(); SetDampeners(true); return(true); } Vector3D deceleration = GetAccelerations(speedDifference) + currentGravity; Vector3D decelerationTimes = speedDifference / deceleration; Vector3D positionAtFullStop = currentPosition + currentVelocity * decelerationTimes + deceleration * decelerationTimes * decelerationTimes / 2; Vector3D maxAccelerationDelta = targetPosition - positionAtFullStop; Vector3D shipAcceleration = GetAccelerations(maxAccelerationDelta); Vector3D acceleration = shipAcceleration + currentGravity; Vector3D accelerationForTick = (maxAccelerationDelta - currentVelocity * DELTA) / DELTA_SQ_2 - currentGravity; Vector3D overrides = Vector3D.Max(-Vector3D.One, Vector3D.Min(Vector3D.One, 0.5 * accelerationForTick / shipAcceleration)) * 100; if (maxAccelerationDelta.X < 0) { overrides.X = -overrides.X; } if (maxAccelerationDelta.Y < 0) { overrides.Y = -overrides.Y; } if (maxAccelerationDelta.Z < 0) { overrides.Z = -overrides.Z; } if (currentVelocity.LengthSquared() >= maxSpeed * maxSpeed && (overrides * currentVelocity).Min() >= -0.01) { ClearThrustersOverride(); return(false); } SetDampeners(decelerationTimes.Max() < DELTA); SetThrustersOverride(overrides); return(false); }
public static Vector3D Center(this IEnumerable <IMyCubeGrid> grids) { Vector3D min = Vector3D.MaxValue; Vector3D max = Vector3D.MinValue; foreach (var grid in grids) { min = Vector3D.Min(min, grid.WorldAABB.Min); max = Vector3D.Max(max, grid.WorldAABB.Max); } return((min + max) / 2.0); }
private void MoveProxy() { var bb = new BoundingBoxD(Vector3D.Min(From.Position, To.Position) - .1f, Vector3D.Max(From.Position, To.Position) + .1f); if (_proxyId >= 0) { Graph.Edges.MoveProxy(_proxyId, in bb, Vector3D.Zero); } else { _proxyId = Graph.Edges.AddProxy(in bb, this, 0); } }
public static MatrixD AsMatrixD(this MyPositionAndOrientation posAndOrient) { var matrix = MatrixD.CreateWorld(posAndOrient.Position, posAndOrient.Forward, posAndOrient.Up); const float offset = 100.0f; if (MyAPIGatewayShortcuts.GetWorldBoundaries == null) { return(matrix); } var bound = MyAPIGatewayShortcuts.GetWorldBoundaries(); matrix.Translation = Vector3D.Min(Vector3D.Max(matrix.Translation, bound.Min + offset), bound.Max - offset); return(matrix); }
public static MyDefinitionId?VoxelMaterialAt(this MyVoxelBase voxel, Vector3D min, Vector3D grow, ref MyStorageData cache) { if (cache == null) { cache = new MyStorageData(); } var shape = new BoundingBoxD(Vector3D.Min(min, min + grow), Vector3D.Max(min, min + grow)); Vector3I voxMin; Vector3I voxMax; Vector3I voxCells; GetVoxelShapeDimensions(voxel, shape, out voxMin, out voxMax, out voxCells); Vector3I_RangeIterator cellsItr = new Vector3I_RangeIterator(ref Vector3I.Zero, ref voxCells); while (cellsItr.IsValid()) { Vector3I cellMinCorner; Vector3I cellMaxCorner; GetCellCorners(ref voxMin, ref voxMax, ref cellsItr, out cellMinCorner, out cellMaxCorner); Vector3I rangeMin = cellMinCorner - 1; Vector3I rangeMax = cellMaxCorner + 1; voxel.Storage.ClampVoxelCoord(ref rangeMin); voxel.Storage.ClampVoxelCoord(ref rangeMax); cache.Resize(rangeMin, rangeMax); voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, rangeMin, rangeMax); var mortonCode = -1; var maxMortonCode = cache.Size3D.Size; while (++mortonCode < maxMortonCode) { Vector3I pos; MyMortonCode3D.Decode(mortonCode, out pos); var content = cache.Content(ref pos); if (content <= MyVoxelConstants.VOXEL_CONTENT_EMPTY) { continue; } var material = cache.Material(ref pos); var def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material); if (def != null) { return(def.Id); } } cellsItr.MoveNext(); } return(null); }
public Solve(List <Vector3D> _points, List <Thetra> _thetras, double[,] _coefficients, double[] _q, Func <double, double, double, double> _exact) { q = _q; points = _points; max = points[0]; min = points[0]; foreach (Vector3D item in points) { max = Vector3D.Max(item, max); min = Vector3D.Min(item, min); } thetras = _thetras; coefficients = _coefficients; exact = _exact; }
/// <summary> /// Constructs a <see cref="SlimMath.BoundingBox"/> that fully contains the given points. /// </summary> /// <param name="points">The points that will be contained by the box.</param> /// <returns>The newly constructed bounding box.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="points"/> is <c>null</c>.</exception> public static BoundingBox FromPoints(Vector3D[] points) { if (points == null) { throw new ArgumentNullException("points"); } Vector3D min = new Vector3D(double.MaxValue); Vector3D max = new Vector3D(double.MinValue); for (int i = 0; i < points.Length; ++i) { Vector3D.Min(ref min, ref points[i], out min); Vector3D.Max(ref max, ref points[i], out max); } return(new BoundingBox(min, max)); }
public void Vector3MinMaxCodeCoverageTest() { Vector3D min = Vector3D.Zero; Vector3D max = Vector3D.One; Vector3D actual; // Min. actual = Vector3D.Min(min, max); Assert.AreEqual(actual, min); actual = Vector3D.Min(max, min); Assert.AreEqual(actual, min); // Max. actual = Vector3D.Max(min, max); Assert.AreEqual(actual, max); actual = Vector3D.Max(max, min); Assert.AreEqual(actual, max); }
public void Vector3MinMaxCodeCoverageTest() { Vector3D <float> min = Vector3D <float> .Zero; Vector3D <float> max = Vector3D <float> .One; Vector3D <float> actual; // Min. actual = Vector3D.Min(min, max); Assert.Equal(actual, min); actual = Vector3D.Min(max, min); Assert.Equal(actual, min); // Max. actual = Vector3D.Max(min, max); Assert.Equal(actual, max); actual = Vector3D.Max(max, min); Assert.Equal(actual, max); }
public void Draw() { MatrixD transfromMatrix = this.Origin.TransformMatrix; Vector3D min = Vector3D.One; Vector3D max = Vector3D.Zero; for (int i = 0; i < 8; i++) { Vector3D corner = World.MySector.MainCamera.WorldToScreen(ref m_corners[i]); min = Vector3D.Min(min, corner); max = Vector3D.Max(max, corner); } Vector3D distProj = max - min; // distance vec in screen coordinates (from 0 to 1, where 1 is screen width(for X) or height(for Y) float lineWidth = BBOX_BORDER_THICKNESS_MODIF / (float)MathHelper.Clamp(distProj.Length(), 0.01, 1); Color boxColor = RenderColor; BoundingBoxD box = new BoundingBoxD(-m_boundingBox.HalfExtent, m_boundingBox.HalfExtent); MySimpleObjectDraw.DrawTransparentBox(ref transfromMatrix, ref box, ref boxColor, MySimpleObjectRasterizer.SolidAndWireframe, 1, lineWidth, "Square", "Square"); if (Engine.Utils.MyFakes.ENABLE_DEBUG_DRAW_COORD_SYS) { //x for (int i = -10; i < 11; i++) { Vector3D v1 = this.Origin.Position + transfromMatrix.Forward * 20 + transfromMatrix.Right * (i * 2.5); Vector3D v2 = this.Origin.Position - transfromMatrix.Forward * 20 + transfromMatrix.Right * (i * 2.5); VRageRender.MyRenderProxy.DebugDrawLine3D(v1, v2, boxColor, boxColor, false); } //y for (int i = -10; i < 11; i++) { Vector3D v1 = this.Origin.Position + transfromMatrix.Right * 20 + transfromMatrix.Forward * (i * 2.5); Vector3D v2 = this.Origin.Position - transfromMatrix.Right * 20 + transfromMatrix.Forward * (i * 2.5); VRageRender.MyRenderProxy.DebugDrawLine3D(v1, v2, boxColor, boxColor, false); } } }
internal void DebugDraw(Vector3I sectorPos, float sectorSize) { foreach (var part in m_instanceParts.Values) { foreach (var data in part.InstanceData) { var dist = (data.LocalMatrix.Translation - Sandbox.Game.World.MySector.MainCamera.Position).Length(); if (dist < 30) { MyRenderProxy.DebugDrawText3D(data.LocalMatrix.Translation, part.SubtypeId.ToString(), Color.Red, (float)(7.0 / dist), true); } } } BoundingBoxD bb = new BoundingBoxD(sectorPos * sectorSize, (sectorPos + Vector3I.One) * sectorSize); BoundingBoxD bb2 = new BoundingBoxD(m_AABB.Min, m_AABB.Max); bb2.Min = Vector3D.Max(bb2.Min, bb.Min); bb2.Max = Vector3D.Min(bb2.Max, bb.Max); MyRenderProxy.DebugDrawAABB(bb, Color.Orange, 1.0f, 1.0f, true); MyRenderProxy.DebugDrawAABB(bb2, Color.OrangeRed, 1.0f, 1.0f, true); }
public void Draw() { MatrixD transfromMatrix = this.Origin.TransformMatrix; Vector3D min = Vector3D.One; Vector3D max = Vector3D.Zero; for (int i = 0; i < 8; i++) { Vector3D corner = World.MySector.MainCamera.WorldToScreen(ref m_corners[i]); min = Vector3D.Min(min, corner); max = Vector3D.Max(max, corner); } Vector3D distProj = max - min; // distance vec in screen coordinates (from 0 to 1, where 1 is screen width(for X) or height(for Y) float lineWidth = BBOX_BORDER_THICKNESS_MODIF / (float)MathHelper.Clamp(distProj.Length(), 0.01, 1); Color boxColor = RenderColor; BoundingBoxD box = new BoundingBoxD(-m_boundingBox.HalfExtent, m_boundingBox.HalfExtent); MySimpleObjectDraw.DrawTransparentBox(ref transfromMatrix, ref box, ref boxColor, MySimpleObjectRasterizer.SolidAndWireframe, 1, lineWidth, "Square", "Square"); }
public static BoundingBoxD CreateFromPoints(IEnumerable <Vector3D> points) { if (points == null) { throw new ArgumentNullException(); } bool flag = false; Vector3D vectord = new Vector3D(double.MaxValue); Vector3D vectord2 = new Vector3D(double.MinValue); foreach (Vector3D vectord3 in points) { Vector3D vectord4 = vectord3; Vector3D.Min(ref vectord, ref vectord4, out vectord); Vector3D.Max(ref vectord2, ref vectord4, out vectord2); flag = true; } if (!flag) { throw new ArgumentException(); } return(new BoundingBoxD(vectord, vectord2)); }
//double IntersectionLineAndSphere(Vector3D centerPoint, double radius, Vector3D lineOrigin, Vector3D lineDir) //{ // // https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection // Vector3D c = centerPoint; // double r = radius; // Vector3D o = lineOrigin; // Vector3D l = lineDir; // double sq1 = Math.Pow(Vector3D.Dot((o - c)*(o - c), l), 2); // double sq2 = l.LengthSquared() * ((o - c).LengthSquared() - r*r); // double sq = sq1 - sq2; // MyRenderProxy.Assert(sq >= 0, "the line needs to be crossing sphere! Some internal bug..."); // double d1 = Vector3D.Dot(l, o - c); // return -d1 + Math.Sqrt(sq); //} MatrixD CreateRigidLightMatrix(Vector3D[] verts, Vector3D lightDir, double zOffset) { // Create orthoghonal vectors: Vector3D lightUp = Math.Abs(Vector3.UnitX.Dot(lightDir)) < 0.99f ? Vector3.UnitX : Vector3.UnitY; Vector3D lightRight = Vector3.Cross(lightDir, lightUp); lightUp = Vector3D.Cross(lightRight, lightDir); lightUp.Normalize(); lightRight.Normalize(); // Look for the most compact encapsulation of verts: ... vMin and vMax will contain corners of encapsulation box with sides defined lightUp, lightRight,and lightDir var lightMatrix = MatrixD.CreateLookAt(new Vector3D(0, 0, 0), lightDir, lightUp); var invLightMatrix = MatrixD.Invert(lightMatrix); Vector3D.Transform(verts, ref lightMatrix, m_tmpCreateOrthoVertsLS); Vector3D vMinLS = m_tmpCreateOrthoVertsLS[0]; Vector3D vMaxLS = m_tmpCreateOrthoVertsLS[0]; for (uint i = 1; i < verts.Length; i++) { vMinLS = Vector3D.Min(vMinLS, m_tmpCreateOrthoVertsLS[i]); vMaxLS = Vector3D.Max(vMaxLS, m_tmpCreateOrthoVertsLS[i]); } Vector3D vMinWS = Vector3D.Transform(vMinLS, ref invLightMatrix); Vector3D vMaxWS = Vector3D.Transform(vMaxLS, ref invLightMatrix); // Create matrices: Vector3D vMinOffsetLS = -(vMaxLS - vMinLS) / 2; Vector3D vMaxOffsetLS = (vMaxLS - vMinLS) / 2; Vector3D vCenterWS = (vMaxWS + vMinWS) / 2; MatrixD matrixLightPlacer = MatrixD.CreateLookAt(vCenterWS, vCenterWS - lightDir, lightUp); MatrixD matrixLightSizer = MatrixD.CreateOrthographicOffCenter(vMinOffsetLS.X, vMaxOffsetLS.X, vMinOffsetLS.Y, vMaxOffsetLS.Y, vMaxOffsetLS.Z + zOffset, vMinOffsetLS.Z); return(matrixLightPlacer * matrixLightSizer); }