2
0
Эх сурвалжийг харах

Added a bunch of WIP stuff to std.geom.

Mark Sibly 8 жил өмнө
parent
commit
9abfef4a0f

+ 0 - 2
modules/std/geom/affinemat3.monkey2

@@ -144,8 +144,6 @@ Struct AffineMat3<T>
 		Return New AffineMat3( sv.x,0,0,sv.y,0,0 )
 	End
 
-	#rem monkeydoc @hidden
-	#end
 	Function Ortho:AffineMat3( left:T,right:T,bottom:T,top:T )
 
 		Local w:=right-left,h:=top-bottom

+ 64 - 27
modules/std/geom/affinemat4.monkey2

@@ -15,33 +15,33 @@ Affine 4x4 matrices are often used for 3d transformations such as scaling, rotat
 Struct AffineMat4<T>
 
 	Field m:Mat3<T>
-	Field v:Vec3<T>
+	Field t:Vec3<T>
 	
 	Method New()
 		m.i.x=1; m.j.y=1; m.k.z=1
 	End
 	
-	Method New( m:Mat3<T>,v:Vec3<T> )
-		Self.m=m; Self.v=v
+	Method New( m:Mat3<T>,t:Vec3<T> )
+		Self.m=m; Self.t=t
 	End
 	
 	Method New( m:Mat3<T> )
 		Self.m=m
 	End
 	
-	Method New( v:Vec3<T> )
-		m.i.x=1; m.j.y=1; m.k.z=1 ; Self.v=v
+	Method New( t:Vec3<T> )
+		m.i.x=1; m.j.y=1; m.k.z=1 ; Self.t=t
 	End
 	
-	Method New( i:Vec3<T>,j:Vec3<T>,k:Vec3<T>,v:Vec3<T> )
-		m.i=i; m.j=j; m.k=k; Self.v=v
+	Method New( i:Vec3<T>,j:Vec3<T>,k:Vec3<T>,t:Vec3<T> )
+		m.i=i; m.j=j; m.k=k; Self.t=t
 	End
 
 	Method New( ix:T,iy:T,iz:T,jx:T,jy:T,jz:T,kx:T,ky:T,kz:T,vx:T,vy:T,vz:T )
 		m.i.x=ix; m.i.y=iy; m.i.z=iz
 		m.j.x=jx; m.j.y=jy; m.j.z=jz
 		m.k.x=kx; m.k.y=ky; m.k.z=kz
-		v.x=vx; v.y=vy; v.z=vz
+		t.x=vx; t.y=vy; t.z=vz
 	End
 	
 	#rem monkeydoc Converts the matrix to a matrix of a different type.
@@ -53,72 +53,109 @@ Struct AffineMat4<T>
 	#rem monkeydoc Converts the matrix to a printable string.
 	#end
 	Operator To:String()
-		Return "AffineMat4("+m+","+v+")"
+		Return "AffineMat4("+m+","+t+")"
 	End
 	
 	#rem monkeydoc Returns the transpose of the matrix.
 	#End
 	Operator~:AffineMat4()
 		Local i:=~m
-		Return New AffineMat4( i,i*-v )
+		Return New AffineMat4( i,i*-t )
 	End
 	
 	#rem monkeydoc Returns the inverse of the matrix.
 	#end
 	Operator-:AffineMat4()
 		Local i:=-m
-		Return New AffineMat4( i,i*-v )
+		Return New AffineMat4( i,i*-t )
 	End
 	
 	#rem monkeydoc Multiplies the matrix by another matrix and returns the result.
 	#end
 	Operator*:AffineMat4( q:AffineMat4 )
-		Return New AffineMat4( m*q.m,m*q.v+v )
+		Return New AffineMat4( m*q.m,m*q.t+t )
 	End
 	
 	#rem monkeydoc Multiplies a vector by the matrix and returns the result.
 	#end
 	Operator*:Vec3<T>( v:Vec3<T> )
 		Return New Vec3<T>( 
-			m.i.x*v.x+m.j.x*v.y+m.k.x*v.z+v.x,
-			m.i.y*v.x+m.j.y*v.y+m.k.y*v.z+v.y,
-			m.i.z*v.x+m.j.z*v.y+m.k.z*v.z+v.z )
+			m.i.x*v.x+m.j.x*v.y+m.k.x*v.z+t.x,
+			m.i.y*v.x+m.j.y*v.y+m.k.y*v.z+t.y,
+			m.i.z*v.x+m.j.z*v.y+m.k.z*v.z+t.z )
 	End
 
 	#rem monkeydoc Applies a translation transformation to the matrix and returns the result.
 	#end
-	Method Translate:AffineMat4( tv:Vec3<T> )
-		Return Self * TranslationMatrix( tv )
+	Method Translate:AffineMat4( tx:T,ty:T,tz:T )
+		Return Self * Translation( tx,ty,tz )
 	End
 	
+	Method Translate:AffineMat4( tv:Vec3<T> )
+		Return Self * Translation( tv )
+	End
+
 	#rem monkeydoc Applies a rotation transformation to the matrix and returns the result.
 	#end
-	Method Rotate:AffineMat4( rv:Vec3<T> )
-		Return Self * RotationMatrix( rv )
+	Method Rotate:AffineMat4( rx:Double,ry:Double,rz:Double )
+		Return Self * Rotation( rx,ry,rz )
+	End
+
+	Method Rotate:AffineMat4( rv:Vec3<Double> )
+		Return Self * Rotation( rv )
 	End
 	
 	#rem monkeydoc Applies a scaling transformation to the matrix and returns the result.
 	#end
-	Method Scale:AffineMat4( rv:Vec3<T> )
-		Return Self * ScalingMatrix( rv )
+	Method Scale:AffineMat4( sx:T,sy:T,sz:T )
+		Return Self * Scaling( sx,sy,sz )
+	End
+	
+	Method Scale:AffineMat4( sv:Vec3<T> )
+		Return Self * Scaling( sv )
 	End
 	
 	#rem monkeydoc Creates a translation matrix.
 	#end
-	Function TranslationMatrix:AffineMat4( tv:Vec3<T> )
+	Function Translation:AffineMat4( tv:Vec3<T> )
 		Return New AffineMat4( tv )
 	End
 	
-	#rem monkeydoc Creates a rotation matrix.
+	Function Translation:AffineMat4( tx:T,ty:T,tz:T )
+		Return New AffineMat4( New Vec3<T>( tx,ty,tz ) )
+	End
+
+	#rem monkeydoc Creates a rotation matrix from a quaternion.
 	#end
-	Function RotationMatrix:AffineMat4( rv:Vec3<T> )
-		Return New AffineMat4( Mat3<T>.RotationMatrix( rv ) )
+	Function Rotation:AffineMat4( quat:Quat<T> )
+		Return New AffineMat4( Mat3<T>.Rotation( quat ) )
+	End
+	
+	#rem monkeydoc Creates a rotation matrix from euler angles.
+	
+	Order of rotation is Yaw * Pitch * Roll.
+	
+	#end
+	Function Rotation:AffineMat4( rv:Vec3<Double> )
+		Return New AffineMat4( Mat3<T>.Rotation( rv ) )
+	End
+	
+	Function Rotation:AffineMat4( rx:Double,ry:Double,rz:Double )
+		Return New AffineMat4( Mat3<T>.Rotation( rx,ry,rz ) )
 	End
 	
 	#rem monkeydoc Creates a scaling matrix.
 	#end
-	Function ScalingMatrix:AffineMat4( sv:Vec3<T> )
-		Return New AffineMat4( Mat3<T>.ScalingMatrix( sv ) )
+	Function Scaling:AffineMat4( sv:Vec3<T> )
+		Return New AffineMat4( Mat3<T>.Scaling( sv ) )
+	End
+	
+	Function Scaling:AffineMat4( sx:T,sy:T,sz:T )
+		Return New AffineMat4( Mat3<T>.Scaling( sx,sy,sz ) )
+	End
+	
+	Function Scaling:AffineMat4( t:T )
+		Return Scaling( t,t,t )
 	End
 	
 End

+ 21 - 0
modules/std/geom/box.monkey2

@@ -9,12 +9,21 @@ Alias Boxf:Box<Float>
 #end
 Struct Box<T>
 
+	Const FullBounds:=New Box( -1000000,-1000000,-1000000,1000000,1000000,1000000 )
+
+	Const EmptyBounds:=New Box( 1000000,1000000,1000000,-1000000,-1000000,-1000000 )
+	
 	Field min:Vec3<T>
 	Field max:Vec3<T>
 	
 	Method New()
 	End
 	
+	Method New( min:T,max:T )
+		Self.min=New Vec3<T>( min )
+		Self.max=New Vec3<T>( max )
+	End
+	
 	Method New( min:Vec3<T>,max:Vec3<T> )
 		Self.min=min
 		Self.max=max
@@ -25,10 +34,22 @@ Struct Box<T>
 		max.x=x1;max.y=y1;max.z=z1
 	End
 	
+	Operator To:String()
+		Return "Box("+min+","+max+")"
+	End
+	
+	Operator To<C>:Box<C>()
+		Return New Box<C>( min,max )
+	End
+	
 	Property Empty:Bool()
 		Return max.x<=min.x Or max.y<=min.y Or max.z<=min.z
 	End
 	
+	Property Center:Vec3<T>()
+		Return (min+max)/2
+	End
+	
 	Property Size:Vec3<T>()
 		Return max-min
 	End

+ 121 - 41
modules/std/geom/mat3.monkey2

@@ -22,12 +22,6 @@ Struct Mat3<T>
 	End
 	
 	Method New( q:Quat<T> )
-		Local xx:=q.v.x*q.v.x , yy:=q.v.y*q.v.y , zz:=q.v.z*q.v.z
-		Local xy:=q.v.x*q.v.y , xz:=q.v.x*q.v.z , yz:=q.v.y*q.v.z
-		Local wx:=q.w*q.v.x   , wy:=q.w*q.v.y   , wz:=q.w*q.v.z
-		i.x=1-2*(yy+zz) ; i.y=  2*(xy-wz) ; i.z=  2*(xz+wy)
-		j.x=  2*(xy+wz) ; j.y=1-2*(xx+zz) ; j.z=  2*(yz-wx)
-		k.x=  2*(xz-wy) ; k.y=  2*(yz+wx) ; k.z=1-2*(xx+yy)
 	End
 	
 	Method New( ix:Float,jy:Float,kz:Float )
@@ -40,39 +34,16 @@ Struct Mat3<T>
 		k.x=kx; k.y=ky; k.z=kz
 	End
 	
-	Method To<C>:Mat3<C>()
+	Operator To<C>:Mat3<C>()
 		Return New Mat3<C>( i,j,k )
 	End
 	
-	Method To:String()
+	Operator To:String()
 		Return "Mat3("+i+","+j+","+k+")"
 	End
 	
-	Method To:Quat<T>()
-		Return New Quat<T>( Self )
-	End
-	
-	Property Determinant:Double()
-		return i.x*(j.y*k.z-j.z*k.y )-i.y*(j.x*k.z-j.z*k.x )+i.z*(j.x*k.y-j.y*k.x )
-	End
-	
-	Property Cofactor:Mat3()
-		Return New Mat3(
-			 (j.y*k.z-j.z*k.y),-(j.x*k.z-j.z*k.x), (j.x*k.y-j.y*k.x),
-			-(i.y*k.z-i.z*k.y), (i.x*k.z-i.z*k.x),-(i.x*k.y-i.y*k.x),
-			 (i.y*j.z-i.z*j.y),-(i.x*j.z-i.z*j.x), (i.x*j.y-i.y*j.x) )
-	End
-	
-	Property Pitch:Double()
-		Return k.Pitch
-	End
-	
-	Property Yaw:Double()
-		Return k.Yaw
-	End
-	
-	Property Roll:Double()
-		Return ATan2( i.y,j.y )
+	Property Determinant:T()
+		Return i.x*(j.y*k.z-j.z*k.y )-i.y*(j.x*k.z-j.z*k.x )+i.z*(j.x*k.y-j.y*k.x )
 	End
 	
 	Operator~:Mat3()
@@ -102,12 +73,83 @@ Struct Mat3<T>
 		Return New Vec3<T>( i.x*v.x+j.x*v.y+k.x*v.z,i.y*v.x+j.y*v.y+k.y*v.z,i.z*v.x+j.z*v.y+k.z*v.z )
 	End
 	
+	Method GetCofactor:Mat3()
+		Return New Mat3(
+			 (j.y*k.z-j.z*k.y),-(j.x*k.z-j.z*k.x), (j.x*k.y-j.y*k.x),
+			-(i.y*k.z-i.z*k.y), (i.x*k.z-i.z*k.x),-(i.x*k.y-i.y*k.x),
+			 (i.y*j.z-i.z*j.y),-(i.x*j.z-i.z*j.x), (i.x*j.y-i.y*j.x) )
+	End
+	
+	Method GetPitch:Double()
+		Return k.Pitch
+	End
+	
+	Method GetYaw:Double()
+		Return k.Yaw
+	End
+	
+	Method GetRoll:Double()
+		Return ATan2( i.y,j.y )
+	End
+	
+	Method GetRotation:Vec3<T>()
+		Return New Vec3<T>( GetPitch(),GetYaw(),GetRoll() )
+	End
+	
+	Method GetQuat:Quat<T>()
+		Local r:Quat<T>
+		Local m:=Orthogonalize()
+		Local t:=m.i.x+m.j.y+m.k.z
+		If t>EPSILON
+			t=Sqrt( t+1 )*2
+			r.v.x=(m.k.y-m.j.z)/t
+			r.v.y=(m.i.z-m.k.x)/t
+			r.v.z=(m.j.x-m.i.y)/t
+			r.w=t/4
+		Else If m.i.x>m.j.y And m.i.x>m.k.z
+			t=Sqrt( m.i.x-m.j.y-m.k.z+1 )*2
+			r.v.x=t/4
+			r.v.y=(m.j.x+m.i.y)/t
+			r.v.z=(m.i.z+m.k.x)/t
+			r.w=(m.k.y-m.j.z)/t
+		Else If m.j.y>m.k.z
+			t=Sqrt( m.j.y-m.k.z-m.i.x+1 )*2
+			r.v.x=(m.j.x+m.i.y)/t
+			r.v.y=t/4
+			r.v.z=(m.k.y+m.j.z)/t
+			r.w=(m.i.z-m.k.x)/t
+		Else
+			t=Sqrt( m.k.z-m.j.y-m.i.x+1 )*2
+			r.v.x=(m.i.z+m.k.x)/t
+			r.v.y=(m.k.y+m.j.z)/t
+			r.v.z=t/4
+			r.w=(m.j.x-m.i.y)/t
+		Endif
+		Return r
+	End
+	
+	Method GetScaling:Vec3<T>()
+		Return New Vec3<T>( i.Length,j.Length,k.Length )
+	End
+	
 	Method Rotate:Mat3( rv:Vec3<T> )
-		Return Self * RotationMatrix( rv )
+		Return Self * Rotation( rv )
+	End
+	
+	Method Rotate:Mat3( rx:Double,ry:Double,rz:Double )
+		Return Self * Rotation( rx,ry,rz )
 	End
 	
 	Method Scale:Mat3( rv:Vec3<T> )
-		Return Self * ScalingMatrix( rv )
+		Return Self * Scaling( rv )
+	End
+
+	Method Scale:Mat3( sx:T,sy:T,sz:T )
+		Return Self * Scaling( sx,sy,sz )
+	End
+	
+	Method Scale:Mat3( t:T )
+		Return Self * Scaling( t )
 	End
 
 	Method Orthogonalize:Mat3()
@@ -115,27 +157,65 @@ Struct Mat3<T>
 		Return New Mat3( j.Cross( k ).Normalize(),k.Cross( i ).Normalize(),k )
 	End
 	
-	Function YawMatrix:Mat3( an:Double )
+	#rem monkeydoc Creates a yaw (y axis) rotation matrix.
+	#end
+	Function Yaw:Mat3( an:Double )
 		Local sin:=Sin(an),cos:=Cos(an)
 		Return New Mat3( cos,0,sin, 0,1,0, -sin,0,cos )
 	End
 	
-	Function PitchMatrix:Mat3( an:Double )
+	#rem monkeydoc Creates a pitch (x axis) rotation matrix.
+	#end
+	Function Pitch:Mat3( an:Double )
 		Local sin:=Sin(an),cos:=Cos(an)
 		return New Mat3( 1,0,0, 0,cos,sin, 0,-sin,cos )
 	End
 	
-	Function RollMatrix:Mat3( an:Double )
+	#rem monkeydoc Creates a roll (z axis) rotation matrix.
+	#end
+	Function Roll:Mat3( an:Double )
 		Local sin:=Sin(an),cos:=Cos(an)
 		Return New Mat3( cos,sin,0, -sin,cos,0, 0,0,1 )
 	End
 	
-	Function RotationMatrix:Mat3( rv:Vec3<T> )
-		Return YawMatrix( rv.y ) * PitchMatrix( rv.x ) * RollMatrix( rv.z )
+	#rem monkeydoc Creates a rotation matrix from a quaternion.
+	#end
+	Function Rotation:Mat3( quat:Quat<T> )
+		Local xx:=quat.v.x*quat.v.x , yy:=quat.v.y*quat.v.y , zz:=quat.v.z*quat.v.z
+		Local xy:=quat.v.x*quat.v.y , xz:=quat.v.x*quat.v.z , yz:=quat.v.y*quat.v.z
+		Local wx:=quat.w*quat.v.x   , wy:=quat.w*quat.v.y   , wz:=quat.w*quat.v.z
+		Local r:Mat3
+		r.i.x=1-2*(yy+zz) ; r.i.y=  2*(xy-wz) ; r.i.z=  2*(xz+wy)
+		r.j.x=  2*(xy+wz) ; r.j.y=1-2*(xx+zz) ; r.j.z=  2*(yz-wx)
+		r.k.x=  2*(xz-wy) ; r.k.y=  2*(yz+wx) ; r.k.z=1-2*(xx+yy)
+		Return r
+	End
+	
+	#rem monkeydoc Creates a rotation matrix from euler angles.
+	
+	Order of rotation is Yaw * Pitch * Roll.
+	
+	#end
+	Function Rotation:Mat3( rv:Vec3<Double> )
+		Return Yaw( rv.y ) * Pitch( rv.x ) * Roll( rv.z )
 	End
 	
-	Function ScalingMatrix:Mat3( sv:Vec3<T> )
+	Function Rotation:Mat3( rx:Double,ry:Double,rz:Double )
+		Return Yaw( ry ) * Pitch( rx ) * Roll( rz )
+	End
+
+	#rem monkeydoc Creates a scaling matrix.
+	#end
+	Function Scaling:Mat3( sv:Vec3<T> )
 		Return New Mat3( sv.x,sv.y,sv.z )
 	End
 
+	Function Scaling:Mat3( sx:T,sy:T,sz:T )
+		Return New Mat3( sx,sy,sz )
+	End
+	
+	Function Scaling:Mat3( t:T )
+		Return New Mat3( t,t,t )
+	End
+	
 End

+ 119 - 14
modules/std/geom/mat4.monkey2

@@ -26,11 +26,16 @@ Struct Mat4<T>
 		Self.i=i;Self.j=j;Self.k=k;Self.t=t
 	End
 	
+	Method New( m:Mat3<T> )
+		i.XYZ=m.i ; j.XYZ=m.j ; k.XYZ=m.k ; t.w=1
+	End
+	
 	Method New( m:AffineMat3<T> )
-		i.x=m.i.x;i.y=m.i.y
-		j.x=m.j.x;j.y=m.j.y
-		k.z=1
-		t.x=m.t.x;t.y=m.t.y;t.w=1
+		i.XY=m.i ; j.XY=m.j ; k.z=1 ; t.XY=m.t ; t.w=1
+	End
+	
+	Method New( m:AffineMat4<T> )
+		i.XYZ=m.m.i ; j.XYZ=m.m.j ; k.XYZ=m.m.k ; t.XYZ=m.t ; t.w=1
 	End
 	
 	Operator*:Mat4( m:Mat4 )
@@ -59,25 +64,125 @@ Struct Mat4<T>
 		Return r
 	End
 	
-	Function Translation:Mat4( tx:T,ty:T,tz:T )
-		Local r:=New Mat4
-		r.t.x=tx;r.t.y=ty;r.t.z=tz
+	Operator*:Mat4( m:AffineMat4<T> )
+
+		Local r:Mat4
+		
+		r.i.x=i.x*m.m.i.x + j.x*m.m.i.y + k.x*m.m.i.z
+		r.i.y=i.y*m.m.i.x + j.y*m.m.i.y + k.y*m.m.i.z
+		r.i.z=i.z*m.m.i.x + j.z*m.m.i.y + k.z*m.m.i.z
+		r.i.w=i.w*m.m.i.x + j.w*m.m.i.y + k.w*m.m.i.z
+		
+		r.j.x=i.x*m.m.j.x + j.x*m.m.j.y + k.x*m.m.j.z
+		r.j.y=i.y*m.m.j.x + j.y*m.m.j.y + k.y*m.m.j.z
+		r.j.z=i.z*m.m.j.x + j.z*m.m.j.y + k.z*m.m.j.z
+		r.j.w=i.w*m.m.j.x + j.w*m.m.j.y + k.w*m.m.j.z
+		
+		r.k.x=i.x*m.m.k.x + j.x*m.m.k.y + k.x*m.m.k.z
+		r.k.y=i.y*m.m.k.x + j.y*m.m.k.y + k.y*m.m.k.z
+		r.k.z=i.z*m.m.k.x + j.z*m.m.k.y + k.z*m.m.k.z
+		r.k.w=i.w*m.m.k.x + j.w*m.m.k.y + k.w*m.m.k.z
+		
+		r.t.x=i.x*m.t.x   + j.x*m.t.y   + k.x*m.t.z + t.x
+		r.t.y=i.y*m.t.x   + j.y*m.t.y   + k.y*m.t.z + t.y
+		r.t.z=i.z*m.t.x   + j.z*m.t.y   + k.z*m.t.z + t.z
+		r.t.w=i.w*m.t.x   + j.w*m.t.y   + k.w*m.t.z + t.w
+		
 		Return r
 	End
 	
-	Function Scale:Mat4( sx:Float,sy:Float,sz:Float )
+	Operator*:Mat4( m:Mat3<T> )
+
 		Local r:Mat4
-		r.i.x=sx;r.j.y=sy;r.k.z=sz;r.t.w=1
+		
+		r.i.x=i.x*m.i.x + j.x*m.i.y + k.x*m.i.z
+		r.i.y=i.y*m.i.x + j.y*m.i.y + k.y*m.i.z
+		r.i.z=i.z*m.i.x + j.z*m.i.y + k.z*m.i.z
+		r.i.w=i.w*m.i.x + j.w*m.i.y + k.w*m.i.z
+		
+		r.j.x=i.x*m.j.x + j.x*m.j.y + k.x*m.j.z
+		r.j.y=i.y*m.j.x + j.y*m.j.y + k.y*m.j.z
+		r.j.z=i.z*m.j.x + j.z*m.j.y + k.z*m.j.z
+		r.j.w=i.w*m.j.x + j.w*m.j.y + k.w*m.j.z
+		
+		r.k.x=i.x*m.k.x + j.x*m.k.y + k.x*m.k.z
+		r.k.y=i.y*m.k.x + j.y*m.k.y + k.y*m.k.z
+		r.k.z=i.z*m.k.x + j.z*m.k.y + k.z*m.k.z
+		r.k.w=i.w*m.k.x + j.w*m.k.y + k.w*m.k.z
+		
+		r.t.x=t.x
+		r.t.y=t.y
+		r.t.z=t.z
+		r.t.w=t.w
+		
+		Return r
+	End
+	
+	#rem monkeydoc Creates a translation matrix.
+	#end
+	Function Translation:Mat4( tv:Vec3<T> )
+		Return Translation( tv.x,tv.y,tv.z )
+	End
+	
+	Function Translation:Mat4( tx:T,ty:T,tz:T )
+		Local r:=New Mat4
+		r.t.x=tx;r.t.y=ty;r.t.z=tz;r.t.w=1
 		Return r
 	End
+
+	#rem monkeydoc Creates a rotation matrix.
+	#end
+	Function Rotation:Mat4( rv:Vec3<Double> )
+		Return Rotation( rv.x,rv.y,rv.z )
+	End
+	
+	Function Rotation:Mat4( rx:Double,ry:Double,rz:Double )
+		Return New Mat4( Mat3<T>.Rotation( rx,ry,rz ) )
+	End
+	
+	#rem monkeydoc Creates a scaling matrix.
+	#end
+	Function Scaling:Mat4( sx:T,sy:T,sz:T )
+		Return New Mat4( sx,sy,sz,1 )
+	End
+	
+	Function Scaling:Mat4( sv:Vec3<T> )
+		Return Scaling( sv.x,sv.y,sv.z )
+	End
 	
-	Function Ortho:Mat4( left:Float,right:Float,bottom:Float,top:Float,near:Float,far:Float )
+	Function Scaling:Mat4( t:T )
+		Return Scaling( t,t,t )
+	End
 
-		Local w:=right-left,h:=top-bottom,d:=far-near
+	#rem monkeydoc Creates an orthographic projection matrix.
+	#End	
+	Function Ortho:Mat4( left:Double,right:Double,bottom:Double,top:Double,near:Double,far:Double )
 
-		Local r:Mat4
-		r.i.x=2/w ; r.j.y=2/h ; r.k.z=2/d
-		r.t=New Vec4<T>( -(right+left)/w,-(top+bottom)/h,-(far+near)/d,1 )
+		Local w:=right-left,h:=top-bottom,d:=far-near,r:Mat4
+
+		r.i.x=2/w
+		r.j.y=2/h
+		r.k.z=2/d
+		r.t.x=-(right+left)/w
+		r.t.y=-(top+bottom)/h
+		r.t.z=-(far+near)/d
+		r.t.w=1
+
+		Return r
+	End
+	
+	Function Frustum:Mat4( left:Double,right:Double,bottom:Double,top:Double,near:Double,far:Double )
+	
+		Local w:=right-left,h:=top-bottom,d:=far-near,near2:=near*2,r:Mat4
+
+		r.i.x=near2/w
+		r.j.y=near2/h
+		r.k.x=(right+left)/w
+		r.k.y=(top+bottom)/h
+		r.k.z=(far+near)/d
+		r.k.w=1
+		r.t.z=-(far*near2)/d
+		
 		Return r
 	End
 	

+ 32 - 52
modules/std/geom/quat.monkey2

@@ -28,36 +28,6 @@ Class Quat<T>
 		v.x=vx ; v.y=vy ; v.z=vz ; Self.w=w
 	End
 	
-	Method New( m:Mat3<T> )
-		m=m.Orthogonalize()
-		Local t:=m.i.x+m.j.y+m.k.z
-		If t>EPSILON
-			t=Sqrt( t+1 )*2
-			v.x=(m.k.y-m.j.z)/t
-			v.y=(m.i.z-m.k.x)/t
-			v.z=(m.j.x-m.i.y)/t
-			w=t/4
-		Else If m.i.x>m.j.y And m.i.x>m.k.z
-			t=Sqrt( m.i.x-m.j.y-m.k.z+1 )*2
-			v.x=t/4
-			v.y=(m.j.x+m.i.y)/t
-			v.z=(m.i.z+m.k.x)/t
-			w=(m.k.y-m.j.z)/t
-		Else If m.j.y>m.k.z
-			t=Sqrt( m.j.y-m.k.z-m.i.x+1 )*2
-			v.x=(m.j.x+m.i.y)/t
-			v.y=t/4
-			v.z=(m.k.y+m.j.z)/t
-			w=(m.i.z-m.k.x)/t
-		Else
-			t=Sqrt( m.k.z-m.j.y-m.i.x+1 )*2
-			v.x=(m.i.z+m.k.x)/t
-			v.y=(m.k.y+m.j.z)/t
-			v.z=t/4
-			w=(m.j.x-m.i.y)/t
-		Endif
-	End
-	
 	Operator To<C>:Quat<C>()
 		Return New Quat<C>( v,w )
 	End
@@ -66,10 +36,6 @@ Class Quat<T>
 		Return "Quat("+v+","+w+")"
 	End
 	
-	Operator To:Mat3<T>()
-		Return New Mat3<T>( Self )
-	End
-	
 	Property Length:Double()
 		Return Sqrt( v.Dot(v) + w*w )
 	End
@@ -85,26 +51,14 @@ Class Quat<T>
 		Local yz:=v.y*v.z , wx:=w*v.x
 		Local xy:=v.x*v.y , wz:=w*v.z
 		Local xx:=v.x*v.x , zz:=v.z*v.z
-		return New Vec3<T>( 2*(xy+wz),1-2*(xx+zz),2*(yz-wx) )
+		Return New Vec3<T>( 2*(xy+wz),1-2*(xx+zz),2*(yz-wx) )
 	End
 	
 	Property K:Vec3<T>()
 		Local xz:=v.x*v.z , wy:=w*v.y
 		Local yz:=v.y*v.z , wx:=w*v.x
 		Local xx:=v.x*v.x , yy:=v.y*v.y
-		return New Vec3<T>( 2*(xz-wy),2*(yz+wx),1-2*(xx+yy) )
-	End
-	
-	Property Yaw:Double()
-		Return K.Yaw
-	End
-	
-	Property Pitch:Double()
-		Return K.Pitch
-	End
-	
-	Property Roll:Double()
-		Return ATan2( I.y,J.y )
+		Return New Vec3<T>( 2*(xz-wy),2*(yz+wx),1-2*(xx+yy) )
 	End
 	
 	Operator-:Quat()
@@ -135,6 +89,18 @@ Class Quat<T>
 		Return New Quat( v/t,w/t )
 	End
 	
+	Method GetYaw:Double()
+		Return K.Yaw
+	End
+	
+	Method GetPitch:Double()
+		Return K.Pitch
+	End
+	
+	Method GetRoll:Double()
+		Return ATan2( I.y,J.y )
+	End
+	
 	Method Dot:Double( q:Quat )
 		Return v.x*q.v.x + v.y*q.v.y + v.z*q.v.z + w*q.w
 	End
@@ -161,10 +127,24 @@ Class Quat<T>
 		Return Self*b + t*a
 	End
 	
-'	Function RotationQuat:Quat( rv:Vec3<T> )
-'	End
+	Function Pitch:Quat( r:Double )
+		Return New Quat( Sin( r/2 ),0,0,Cos( r/2 ) )
+	End
+
+	Function Yaw:Quat( r:Double )
+		Return New Quat( 0,Sin( r/2 ),0,Cos( r/2 ) )
+	End
+
+	Function Roll:Quat( r:Double )
+		Return New Quat( 0,0,Sin( r/2 ),Cos( r/2 ) )
+	End
+
+	Function Rotation:Quat( rv:Vec3<Double> )
+		Return Yaw( rv.y ) * Pitch( rv.x ) * Roll( rv.z )
+	End
 	
-'	Function AxisAngleQuat:Quat( axis:Vec3<T>,angle:Double )
-'	End
+	Function Rotation:Quat( rx:Double,ry:Double,rz:Double )
+		Return Yaw( ry ) * Pitch( rx ) * Roll( rz )
+	End
 
 End

+ 6 - 0
modules/std/geom/vec3.monkey2

@@ -54,6 +54,12 @@ Struct Vec3<T>
 		Self.z=z
 	End
 	
+	Property XY:Vec2<T>()
+		Return New Vec2<T>( x,y )
+	Setter( xy:Vec2<T> )
+		x=xy.x;y=xy.y
+	End
+	
 	Operator-:Vec3()
 		Return New Vec3( -x,-y,-z )
 	End

+ 20 - 0
modules/std/geom/vec4.monkey2

@@ -57,6 +57,26 @@ Struct Vec4<T>
 		Self.w=w
 	End
 	
+	Property XY:Vec2<T>()
+		Return New Vec2<T>( x,y )
+	Setter( xy:Vec2<T> )
+		x=xy.x;y=xy.y
+	End
+	
+	Property XYZ:Vec3<T>()
+		Return New Vec3<T>( x,y,z )
+	Setter( xyz:Vec3<T> )
+		x=xyz.x;y=xyz.y;z=xyz.z
+	End
+	
+	Operator To:String()
+		Return "Vec4("+x+","+y+","+z+","+w+")"
+	End
+	
+	Operator To<C>:Vec4<C>()
+		Return New Vec4<C>( x,y,z,w )
+	End
+	
 	Operator-:Vec4()
 		Return New Vec4( -x,-y,-z,-w )
 	End