@@ -181,18 +181,26 @@ public void PointAt()
181181 [ TestMethod ]
182182 public void ModelMatrix ( )
183183 {
184- var transform = Transform . GetInstance ( ) ;
184+ // 1. Initialize the Transform with the translation already baked in!
185+ // Using the GetInstance overload that accepts translation, scale, and rotation.
186+ var transform = Transform . GetInstance (
187+ translation : new Vector3D ( 0 , 0 , 3 ) , // Here is your Z = 3
188+ scale : Vector3D . UnitVector ,
189+ rotation : Vector3D . ZeroVector
190+ ) ;
191+ transform . Position = new Vector3D ( 0 , 0 , 0 ) ;
185192
193+ // 2. Use the safe constructor for the Matrix
186194 var matrix = new double [ , ] { { 1 , 0 , 0 , 0 } , { 0 , 1 , 0 , 0 } , { 0 , 0 , 1 , 0 } , { 0 , 0 , 3 , 1 } } ;
195+ var model = new BaseMatrix ( matrix ) ;
187196
188- var model = new BaseMatrix { Matrix = matrix } ;
189- transform . Position = new Vector3D ( 0 , 0 , 0 ) ;
190- transform . Translation . Z = 3 ;
191197 var cache = Projection3DCamera . ModelMatrix ( transform ) ;
192198
193199 var check = model . Equals ( cache ) ;
194200 Trace . WriteLine ( cache . ToString ( ) ) ;
195- Trace . WriteLine ( transform . Position . ToString ( ) ) ;
201+
202+ // Safely unwrap the nullable Position for the Trace
203+ Trace . WriteLine ( transform . Position ? . ToString ( ) ?? "null" ) ;
196204
197205 Assert . IsTrue ( check , "Not the Correct Model Matrix" ) ;
198206
@@ -248,35 +256,31 @@ public void ModelMatrix()
248256 /// Multiplies the matrix vector.
249257 /// </summary>
250258 /// <param name="i">The i.</param>
251- /// <param name="matProj">The mat proj .</param>
259+ /// <param name="matProj">The projection matrix .</param>
252260 /// <returns>The Projection Vector</returns>
253261 private static Vector3D MultiplyMatrixVector ( Vector3D i , BaseMatrix matProj )
254262 {
255- var o = new Vector3D
256- {
257- X = ( i . X * matProj . Matrix [ 0 , 0 ] ) + ( i . Y * matProj . Matrix [ 1 , 0 ] ) + ( i . Z * matProj . Matrix [ 2 , 0 ] ) +
258- matProj . Matrix [ 3 , 0 ] ,
259- Y = ( i . X * matProj . Matrix [ 0 , 1 ] ) + ( i . Y * matProj . Matrix [ 1 , 1 ] ) + ( i . Z * matProj . Matrix [ 2 , 1 ] ) +
260- matProj . Matrix [ 3 , 1 ] ,
261- Z = ( i . X * matProj . Matrix [ 0 , 2 ] ) + ( i . Y * matProj . Matrix [ 1 , 2 ] ) + ( i . Z * matProj . Matrix [ 2 , 2 ] ) +
262- matProj . Matrix [ 3 , 2 ]
263- } ;
263+ // 1. Calculate raw transformed coordinates into local variables first
264+ double newX = ( i . X * matProj . Matrix [ 0 , 0 ] ) + ( i . Y * matProj . Matrix [ 1 , 0 ] ) + ( i . Z * matProj . Matrix [ 2 , 0 ] ) + matProj . Matrix [ 3 , 0 ] ;
265+ double newY = ( i . X * matProj . Matrix [ 0 , 1 ] ) + ( i . Y * matProj . Matrix [ 1 , 1 ] ) + ( i . Z * matProj . Matrix [ 2 , 1 ] ) + matProj . Matrix [ 3 , 1 ] ;
266+ double newZ = ( i . X * matProj . Matrix [ 0 , 2 ] ) + ( i . Y * matProj . Matrix [ 1 , 2 ] ) + ( i . Z * matProj . Matrix [ 2 , 2 ] ) + matProj . Matrix [ 3 , 2 ] ;
264267
265- var w = ( i . X * matProj . Matrix [ 0 , 3 ] ) + ( i . Y * matProj . Matrix [ 1 , 3 ] ) + ( i . Z * matProj . Matrix [ 2 , 3 ] ) +
266- matProj . Matrix [ 3 , 3 ] ;
268+ // 2. Calculate W (the homogeneous coordinate)
269+ double w = ( i . X * matProj . Matrix [ 0 , 3 ] ) + ( i . Y * matProj . Matrix [ 1 , 3 ] ) + ( i . Z * matProj . Matrix [ 2 , 3 ] ) + matProj . Matrix [ 3 , 3 ] ;
267270
268271 w = Math . Round ( w , 2 ) ;
269272
270- if ( w == 0.0f )
273+ // 3. Perform the Perspective Divide if W is not zero
274+ // Note: Comparing exact double to 0.0f is risky. A tiny tolerance check is safer.
275+ if ( Math . Abs ( w ) > 0.0001 )
271276 {
272- return o ;
277+ newX /= w ;
278+ newY /= w ;
279+ newZ /= w ;
273280 }
274281
275- o . X /= w ;
276- o . Y /= w ;
277- o . Z /= w ;
278-
279- return o ;
282+ // 4. Create and return the immutable struct ONCE with the final, perfect values
283+ return new Vector3D ( newX , newY , newZ , w ) ;
280284 }
281285 }
282286}
0 commit comments