Browse Source

WIP geom additions.

Mark Sibly 8 years ago
parent
commit
942d79036b

+ 124 - 0
modules/std/geom/affinemat4.monkey2

@@ -0,0 +1,124 @@
+
+Namespace std.geom
+
+#rem monkeydoc @hidden Convenience type alias for AffineMat4\<Float\>
+#end
+Alias AffineMat4f:AffineMat4<Float>
+
+#rem monkeydoc @hidden Affine 4x4 matrix class.
+
+An affine 4x4 matrix is a 4x4 matrix whose right hand column is always 0,0,0,1.
+
+Affine 4x4 matrices are often used for 3d transformations such as scaling, rotation and translation.
+
+#end
+Struct AffineMat4<T>
+
+	Field m:Mat3<T>
+	Field v: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
+	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
+	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
+	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
+	End
+	
+	#rem monkeydoc Converts the matrix to a matrix of a different type.
+	#end
+	Operator To<C>:AffineMat4<C>()
+		Return New AffineMat4<C>( m,t )
+	End 
+	
+	#rem monkeydoc Converts the matrix to a printable string.
+	#end
+	Operator To:String()
+		Return "AffineMat4("+m+","+v+")"
+	End
+	
+	#rem monkeydoc Returns the transpose of the matrix.
+	#End
+	Operator~:AffineMat4()
+		Local i:=~m
+		Return New AffineMat4( i,i*-v )
+	End
+	
+	#rem monkeydoc Returns the inverse of the matrix.
+	#end
+	Operator-:AffineMat4()
+		Local i:=-m
+		Return New AffineMat4( i,i*-v )
+	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 )
+	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 )
+	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 )
+	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 )
+	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 )
+	End
+	
+	#rem monkeydoc Creates a translation matrix.
+	#end
+	Function TranslationMatrix:AffineMat4( tv:Vec3<T> )
+		Return New AffineMat4( tv )
+	End
+	
+	#rem monkeydoc Creates a rotation matrix.
+	#end
+	Function RotationMatrix:AffineMat4( rv:Vec3<T> )
+		Return New AffineMat4( Mat3<T>.RotationMatrix( rv ) )
+	End
+	
+	#rem monkeydoc Creates a scaling matrix.
+	#end
+	Function ScalingMatrix:AffineMat4( sv:Vec3<T> )
+		Return New AffineMat4( Mat3<T>.ScalingMatrix( sv ) )
+	End
+	
+End

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

@@ -0,0 +1,134 @@
+
+Namespace std.geom
+
+#rem monkeydoc @hidden
+#end
+Alias Boxf:Box<Float>
+
+#rem monkeydoc @hidden
+#end
+Struct Box<T>
+
+	Field min:Vec3<T>
+	Field max:Vec3<T>
+	
+	Method New()
+	End
+	
+	Method New( min:Vec3<T>,max:Vec3<T> )
+		Self.min=min
+		Self.max=max
+	End
+	
+	Method New( x0:T,y0:T,z0:T,x1:T,y1:T,z1:T )
+		min.x=x0;min.y=y0;min.z=z0
+		max.x=x1;max.y=y1;max.z=z1
+	End
+	
+	Property Empty:Bool()
+		Return max.x<=min.x Or max.y<=min.y Or max.z<=min.z
+	End
+	
+	Property Size:Vec3<T>()
+		Return max-min
+	End
+	
+	Operator+:Box( v:Vec3<T> )
+		Return New Box( min+v,max+v )
+	End
+	
+	Operator+=( v:Vec3<T> )
+		min+=v
+		max+=v
+	End
+	
+	Operator-:Box( v:Vec3<T> )
+		Return New Box( min-v,max-v )
+	End
+	
+	Operator-=( v:Vec3<T> )
+		min-=v
+		max-=v
+	End
+	
+	Operator&:Box( box:Box )
+		Return New Box(
+			Max( min.x,box.min.x ),
+			Max( min.y,box.min.y ),
+			Max( min.z,box.min.z ),
+			Min( max.x,box.max.x ),
+			Min( max.y,box.max.y ),
+			Min( max.z,box.max.z ) )
+	End
+	
+	Operator&=( box:Box )
+		min.x=Max( min.x,box.min.x )
+		min.y=Max( min.y,box.min.y )
+		min.z=Max( min.z,box.min.z )
+		max.x=Min( max.x,box.max.x )
+		max.y=Min( max.y,box.max.y )
+		max.z=Min( max.z,box.max.z )
+	End
+	
+	Operator|:Box( box:Box )
+		Return New Box(
+			Min( min.x,box.min.x ),
+			Min( min.y,box.min.y ),
+			Min( min.z,box.min.z ),
+			Max( max.x,box.max.x ),
+			Max( max.y,box.max.y ),
+			Max( max.z,box.max.z ) )
+	End
+	
+	Operator|=( box:Box )
+		min.x=Min( min.x,box.min.x )
+		min.y=Min( min.y,box.min.y )
+		min.z=Min( min.z,box.min.z )
+		max.x=Max( max.x,box.max.x )
+		max.y=Max( max.y,box.max.y )
+		max.z=Max( max.z,box.max.z )
+	End
+	
+	Operator|:Box( p:Vec3<T> )
+		Return New Box(
+			Min( min.x,p.x ),
+			Min( min.x,p.y ),
+			Min( min.x,p.z ),
+			Max( max.x,p.x ),
+			Max( max.y,p.y ),
+			Max( max.z,p.z ) )
+	End
+	
+	Operator|=( p:Vec3<T> )
+		min.x=Min( min.x,p.x )
+		min.y=Min( min.x,p.y )
+		min.z=Min( min.x,p.z )
+		max.x=Max( max.x,p.x )
+		max.y=Max( max.y,p.y )
+		max.z=Max( max.z,p.z )
+	End
+	
+	Method Contains:bool( box:Box )
+		Return min.x>=box.min.x And max.x<=box.max.x And min.y>=box.min.y And max.y<=box.max.y And min.z>=box.min.z And min.z<=box.max.z
+	End
+	
+	Method Intersects:Bool( box:Box )
+		Return min.x<box.max.x And max.x>box.min.x And min.y<box.max.y And max.y>box.min.y And min.z<box.max.z And max.z>box.min.z
+	End
+	
+	Method Corner:Vec3<T>( index:int )
+		Select index
+		Case 0 Return min
+		case 1 Return New Vec3<T>( max.x,min.y,min.z )
+		case 2 Return New Vec3<T>( min.x,max.y,min.z )
+		case 3 Return New Vec3<T>( max.x,max.y,min.z )
+		Case 4 Return New Vec3<T>( min.x,min.y,max.z )
+		Case 5 Return New Vec3<T>( max.x,min.y,max.z )
+		Case 6 Return New Vec3<T>( min.x,max.y,max.z )
+		Case 7 Return max
+		End
+		RuntimeError( "Invalid box corner index: "+index )
+		Return Null
+	End
+	
+End

+ 38 - 0
modules/std/geom/line.monkey2

@@ -0,0 +1,38 @@
+
+Namespace std.geom
+
+#rem monkeydoc @hidden
+#end
+Alias Linef:Line<Float>
+
+#rem monkeydoc @hidden
+#end
+Struct Line<T>
+
+	Field o:Vec3<T>
+	Field d:Vec3<T>
+	
+	Method New()
+	End
+	
+	Method New( o:Vec3<T>,d:Vec3<T> )
+		Self.o=o;Self.d=d
+	End
+	
+	Operator-:Line()
+		Return New Line( o,-d )
+	End
+	
+	Operator+:Line( v:Vec3<T> )
+		Return New Line( o+v,d )
+	End
+	
+	Operator-:Line( v:Vec3<T> )
+		Return New Line( o-v,d )
+	End
+	
+	Method Nearest:Vec3<T>( p:Vec3<T> )
+		Return o+d*( d.Dot( p-o )/d.Dot( d ) )
+	End
+
+End

+ 115 - 4
modules/std/geom/mat3.monkey2

@@ -18,13 +18,124 @@ Struct Mat3<T>
 	End
 	
 	Method New( i:Vec3<T>,j:Vec3<T>,k:Vec3<T> )
-		Self.i=i;Self.j=j;Self.k=k
+		Self.i=i; Self.j=j; Self.k=k
+	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 )
+		i.x=ix; j.y=jy; k.z=kz
 	End
 	
 	Method New( ix:T,iy:T,iz:T,jx:T,jy:T,jz:T,kx:T,ky:T,kz:T )
-		Self.i.x=ix;Self.i.y=iy;Self.i.z=iz
-		Self.j.x=jx;Self.j.y=jy;Self.j.z=jz
-		Self.k.x=jx;Self.k.y=jy;Self.k.z=kz
+		i.x=ix; i.y=iy; i.z=iz
+		j.x=jx; j.y=jy; j.z=jz
+		k.x=kx; k.y=ky; k.z=kz
+	End
+	
+	Method To<C>:Mat3<C>()
+		Return New Mat3<C>( i,j,k )
+	End
+	
+	Method 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 )
+	End
+	
+	Operator~:Mat3()
+		Return New Mat3( i.x,j.x,k.x, i.y,j.y,k.y, i.z,j.z,k.z )
+	End
+	
+	Operator-:Mat3()
+		Local t:=1.0/Determinant
+		Return New Mat3(
+			 t*(j.y*k.z-j.z*k.y),-t*(i.y*k.z-i.z*k.y), t*(i.y*j.z-i.z*j.y),
+			-t*(j.x*k.z-j.z*k.x), t*(i.x*k.z-i.z*k.x),-t*(i.x*j.z-i.z*j.x),
+			 t*(j.x*k.y-j.y*k.x),-t*(i.x*k.y-i.y*k.x), t*(i.x*j.y-i.y*j.x) )
+	End
+	
+	Operator*:Mat3( m:Mat3 )
+		Return New Mat3(
+			i.x*m.i.x+j.x*m.i.y+k.x*m.i.z, i.y*m.i.x+j.y*m.i.y+k.y*m.i.z, i.z*m.i.x+j.z*m.i.y+k.z*m.i.z,
+			i.x*m.j.x+j.x*m.j.y+k.x*m.j.z, i.y*m.j.x+j.y*m.j.y+k.y*m.j.z, i.z*m.j.x+j.z*m.j.y+k.z*m.j.z,
+			i.x*m.k.x+j.x*m.k.y+k.x*m.k.z, i.y*m.k.x+j.y*m.k.y+k.y*m.k.z, i.z*m.k.x+j.z*m.k.y+k.z*m.k.z )
+	End
+	
+	Operator*:Mat3( q:Quat<T> )
+		Return Self * New Mat3( q )
+	End
+	
+	Operator*:Vec3<T>( v:Vec3<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 Rotate:Mat3( rv:Vec3<T> )
+		Return Self * RotationMatrix( rv )
+	End
+	
+	Method Scale:Mat3( rv:Vec3<T> )
+		Return Self * ScalingMatrix( rv )
+	End
+
+	Method Orthogonalize:Mat3()
+		Local k:=Self.k.Normalize()
+		Return New Mat3( j.Cross( k ).Normalize(),k.Cross( i ).Normalize(),k )
+	End
+	
+	Function YawMatrix: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 )
+		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 )
+		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 )
+	End
+	
+	Function ScalingMatrix:Mat3( sv:Vec3<T> )
+		Return New Mat3( sv.x,sv.y,sv.z )
 	End
 
 End

+ 45 - 0
modules/std/geom/plane.monkey2

@@ -0,0 +1,45 @@
+
+Namespace std.geom
+
+#rem monkeydoc @hidden
+#end
+Alias Planef:Plane<Float>
+
+#rem monkeydoc @hidden
+#end
+Struct Plane<T>
+
+	Field n:Vec3<T>
+	Field d:T
+	
+	Method New()
+	End
+	
+	Method New( n:Vec3<T>,d:T )
+		Self.n=n
+		Self.d=d
+	End
+	
+	Method New( p:Vec3<T>,n:Vec3<T> )
+		Self.n=n
+		Self.d=-n.Dot( p )
+	End
+	
+	Method New( v0:Vec3<T>,v1:Vec3<T>,v2:Vec3<T> )
+		n=(v1-v0).Cross(v2-v0).Normalize()
+		d=-n.Dot( v0 )
+	End
+	
+	Operator-:Plane()
+		Return New Plane( -n,-d )
+	End
+	
+	Method Distance:Double( p:Vec3<T> )
+		return n.Dot( p )+d
+	End
+
+	Method Nearest:Vec3<T>( p:Vec3<T> )
+		Return p-n*Distance( p )
+	End
+	
+End

+ 170 - 0
modules/std/geom/quat.monkey2

@@ -0,0 +1,170 @@
+
+Namespace std.geom
+
+#rem monkeydoc @hidden
+#end
+Const EPSILON:=0
+
+#rem monkeydoc @hidden
+#end
+Alias Quatf:Quat<Float>
+
+#rem monkeydoc @hidden
+#end
+Class Quat<T>
+
+	Field v:Vec3<T>
+	Field w:T
+	
+	Method New()
+		w=1
+	End
+	
+	Method New( v:Vec3<T>,w:Float )
+		Self.v=v; Self.w=w
+	End
+	
+	Method New( vx:T,vy:T,vz:T,w: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
+	
+	Method To:String()
+		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
+	
+	Property I:Vec3<T>()
+		Local xz:=v.x*v.z , wy:=w*v.y
+		Local xy:=v.x*v.y , wz:=w*v.z
+		Local yy:=v.y*v.y , zz:=v.z*v.z
+		Return New Vec3<T>( 1-2*(yy+zz),2*(xy-wz),2*(xz+wy) )
+	End
+
+	Property J:Vec3<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) )
+	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 )
+	End
+	
+	Operator-:Quat()
+		Return New Quat( -v,w )
+	End
+	
+	Operator+:Quat( q:Quat )
+		Return New Quat( v+q.v,w+q.w )
+	End
+	
+	Operator-:Quat( q:Quat )
+		Return New Quat( v-q.v,w-q.w )
+	End
+	
+	Operator*:Quat( q:Quat )
+		Return New Quat( q.v.Cross( v )+q.v*w+v*q.w, w*q.w-v.Dot( q.v ) )
+	End
+	
+	Operator*:Vec3<T>( v:Vec3<T> )
+		Return (Self * New Quat( v,0 ) * -Self).v
+	End
+	
+	Operator*:Quat( t:Double )
+		Return New Quat( v*t,w*t )
+	End
+	
+	Operator/:Quat( t:Double )
+		Return New Quat( v/t,w/t )
+	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
+	
+	Method Normalize:Quat()
+		Return Self/Length
+	End
+	
+	Method Slerp:Quat( q:Quat,a:Double )
+		Local t:=q
+		Local b:=1-a
+		Local d:=Dot( q )
+		If d<0 
+			t.v=-t.v
+			t.w=-t.w
+			d=-d
+		Endif
+		If d<1-EPSILON
+			Local om:=ACos( d )
+			Local si:=Sin( om )
+			a=Sin( a*om )/si
+			b=Sin( b*om )/si
+		Endif
+		Return Self*b + t*a
+	End
+	
+'	Function RotationQuat:Quat( rv:Vec3<T> )
+'	End
+	
+'	Function AxisAngleQuat:Quat( axis:Vec3<T>,angle:Double )
+'	End
+
+End

+ 7 - 0
modules/std/geom/vec2.monkey2

@@ -134,6 +134,13 @@ Struct Vec2<T>
 		Return x*v.x+y*v.y
 	End
 	
+	#rem monkeydoc Computes the distance from this vector to another.
+	#end
+	Method Distance:Double( v:Vec2 )
+		Local d:=v-Self
+		Return Sqrt( d.Dot( d ) )
+	End
+	
 	#rem monkeydoc Normalizes the vector and returns the result.
 	#end
 	Method Normalize:Vec2()

+ 21 - 5
modules/std/geom/vec3.monkey2

@@ -28,6 +28,14 @@ Struct Vec3<T>
 		Self.x=v.x;Self.y=v.y;Self.z=z
 	End
 	
+	Method To<C>:Vec3<C>()
+		Return New Vec3<C>( x,y,z )
+	End
+	
+	Method To:String()
+		Return "Vec3("+x+","+y+","+z+")"
+	End
+	
 	Property X:T()
 		Return x
 	Setter( x:T )
@@ -82,13 +90,25 @@ Struct Vec3<T>
 		Return New Vec3( x-s,y-s,z-s )
 	End
 	
+	Property Pitch:Double()
+		return -ATan2( y,Sqrt( x*x+z*z ) )
+	End
+
+	Property Yaw:Double()
+		return -ATan2( x,z )
+	End
+	
 	Property Length:Double()
 		Return Sqrt( x*x+y*y+z*z )
 	End
-
+	
 	Method Dot:Double( v:Vec3 )
 		Return x*v.x+y*v.y+z*v.z
 	End
+
+	Method Cross:Vec3( v:Vec3 )
+		Return New Vec3( y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x )
+	End
 	
 	Method Normalize:Vec3()
 		Return Self/Length
@@ -97,9 +117,5 @@ Struct Vec3<T>
 	Method Blend:Vec3( v:Vec3,alpha:Double )
 		Return New Vec3( (v.x-x)*alpha+x,(v.y-y)*alpha+y,(v.z-z)*alpha+z )
 	End
-	
-	Method ToString:String()
-		Return "Vec3("+x+","+y+","+z+")"
-	End
 
 End

+ 14 - 6
modules/std/std.monkey2

@@ -22,15 +22,23 @@ Namespace std
 #Import "memory/databuffer"
 #Import "memory/datastream"
 
-#Import "geom/vec2"
-#Import "geom/vec3"
-#Import "geom/vec4"
+#Import "geom/affinemat3"
+#Import "geom/affinemat4"
+#Import "geom/axis"
+#Import "geom/box"
+#Import "geom/line"
 #Import "geom/mat3"
 #Import "geom/mat4"
-#Import "geom/affinemat3"
-'#Import "geom/affinemat4"
+#Import "geom/plane"
+#Import "geom/quat"
 #Import "geom/rect"
-#Import "geom/axis"
+#Import "geom/vec2"
+#Import "geom/vec3"
+#Import "geom/vec4"
+
+#Import "geom/plane"
+#Import "geom/box"
+#Import "geom/line"
 
 #Import "graphics/pixelformat"
 #Import "graphics/pixmap"