MiniB3D patch page thought

BlitzMax Modules Forums/MiniB3D/MiniB3D patch page thought

ive been thinking lately about MiniB3D and updating it. i really hate to break off the mainline development as moving in changes each release would start to be painful. i fully understand simon's position and his decision to keep it simple. at the same time, i think there is a lot of functionality out there that can benefit MiniB3D but is not in the mainline development. then hybrids patch page for Irrlicht came to mind. basically its a page of .patch files that fix or add functionality to Irrlicht but is not in the mainline development. i would be happy to host/maintain the site as well as provide a few patches if there is interest. it would mean others submitting your patches to me and maintaining them as well. while i would love to do that i simply dont have the time. to see an example, the Irrlicht patch page can be found at:

http://parsys.informatik.uni-oldenburg.de/~hybrid/irrlicht/

i can also write a quick tutorial on creating patches as well. thoughts?

Good idea.
Excellent idea, in fact.

Such a site would need some pretty wisely set up versioning / dependency stuff, but it could be done and it would keep our wishes for more out of Simon's hair :)


(And on the topic of MiniB3d... it truly is a beautiful piece of work).

I certainly like the idea if it turns out to be maintainable.

If you initiate it gman i got faith it will work out ;)

Good idea gman! I guess I could host the patches on my own page, it would be easy to setup. No idea how patches work though, so that tutorial would be appreciated.

very glad you like the concept simon :)

i will attempt to make an example of my factory modification for MiniB3D. this wraps all the new statements into factory so that a developer can extend the base types the engine uses. ie if the dev wanted to add something to TMesh, then they can extend TMesh, implement their new TMesh in the factory, and the engine will use the extended TMesh for everything.

first you will need a patch tool. this is pretty much stock on linux systems, but for windows its a different story. download the windows unix tools at:

http://unxutils.sourceforge.net/

after extraction, copy the UnixUtils\usr\local\wbin\patch.exe and diff.exe files to the MiniB3D root (same as where MiniB3D.bmx resides).

i have two batch files, one for creating a patch and one for applying a patch.

create.bat
diff -U 10 MiniB3D_orig.bmx MiniB3D.bmx > %1.patch

apply.bat
patch -p1 < %1.patch

both bat files take a parameter of the name of the patch.

make a copy of the original MiniB3D.bmx and call it MiniB3D_orig.bmx.

make all modifications for a certain patch to MiniB3D.bmx. in my case the MiniB3D factory. when you are ready to make the patch, from the command line in the MiniB3D directory call:


create patchname


where "patchname" is the name of the patch file you want to create. in my case i used:

create factory


the resulting file should be called "patchname.patch" or in my case "factory.patch". this file contains the differences between the original MiniB3D.bmx and my factory version.

now, to apply the patch, rename the current MiniB3D.bmx to MiniB3D_factory.bmx. copy MiniB3D_orig.bmx and call it MiniB3D.bmx. MiniB3D.bmx should now be the stock MiniB3D file.

call the apply bat file from the command line like:

apply "patchname"


in this case run:

apply factory


this will apply the patch file to the MiniB3D.bmx file. it does do a decent job with differences in the files so adding a patch to a file already patched by a different patch or one with modifications will work. if another patch modifies a line or a line has been edited that this one was supposed to patch it will generate a file of lines that could not be patched so the differences can be worked out by the dev.

this is quick and dirty so i expect questions :) for reference, my created patch file looks like:
--- MiniB3D_orig.bmx	Mon Aug 28 18:58:02 2006
+++ MiniB3D.bmx	Mon Sep 25 17:56:18 2006
@@ -13,21 +13,84 @@
 ' * TurnEntity isn't working 100% the same as in B3D yet
 
 Import BRL.PixMap
 Import Pub.Glew
 Import BRL.GLGraphics
 Import BRL.Retro
 
 Strict
 
 Global cno=0 ' used by DebugEntity
+Global _gFactory:TMiniB3DFactory=Null
 
+Type TMiniB3DFactory
+	Method New()
+	    ' global instance of the factory
+		_gFactory=Self
+	EndMethod
+	
+	Method generateMatrix:TMatrix()
+		Return New TMatrix
+	EndMethod
+	
+	Method generateVector:TVector()
+		Return New TVector
+	EndMethod
+	
+	Method generateMesh:TMesh()
+		Return New TMesh
+	EndMethod
+	
+	Method generateLight:TLight()
+		Return New TLight
+	EndMethod
+	
+	Method generateBrush:TBrush()
+		Return New TBrush
+	EndMethod
+	
+	Method generateCamera:TCamera()
+		Return New TCamera
+	EndMethod
+	
+	Method generatePivot:TPivot()
+		Return New TPivot
+	EndMethod
+	
+	Method generateSurface:TSurface()
+		Return New TSurface
+	EndMethod
+	
+	Method generateSprite:TSprite()
+		Return New TSprite
+	EndMethod
+	
+	Method generateBone:TBone()
+		Return New TBone
+	EndMethod
+	
+	Method generateTextureFilter:TTextureFilter()
+		Return New TTextureFilter
+	EndMethod
+	
+	Method generateTexture:TTexture()
+		Return New TTexture
+	EndMethod
+	
+	Method generateKeys:TKeys()
+		Return New TKeys
+	EndMethod
+End Type
+
+' create the instance of the factory
+New TMiniB3DFactory
+	
 Type TGlobal
 
 	Global width,height,mode,depth,rate
 	Global ambient_red#=0.5,ambient_green#=0.5,ambient_blue#=0.5
 
 	Function Graphics3D(w,h,d=0,m=0,r=60)
 	
 		width=w
 		height=h
 		depth=d
@@ -357,28 +420,28 @@
 End Type
 
 Type TEntity
 	
 	Global entity_list:TList=CreateList()
 
 	Field child_list:TList=CreateList()
 
 	Field parent:TEntity
 
-	Field mat:TMatrix=New TMatrix
+	Field mat:TMatrix=_gFactory.generateMatrix()
 	Field px#,py#,pz#,sx#=1.0,sy#=1.0,sz#=1.0,rx#,ry#,rz#,qw#,qx#,qy#,qz#
 	Field order,alpha_order#
 	Field hidden=False
 	Field name$
 	Field class$
 	'Field red#=1.0,green#=1.0,blue#=1.0,alpha#=1.0,shine#,blend,fx
-	Field brush:TBrush=New TBrush
+	Field brush:TBrush=_gFactory.generateBrush()
 	
 	Field radius#
 	
 	Field anim ' true if mesh contains anim data
 	Field anim_render ' true to render as anim mesh
 	Field anim_mode
 	Field anim_time#
 	Field anim_speed#
 	Field anim_seq
 	Field anim_trans
@@ -449,21 +512,21 @@
 		If glob=True And parent<>Null
 			
 			px=px-parent.EntityX(True)
 			py=py-parent.EntityY(True)
 			pz=pz+parent.EntityZ(True) ' z reversed
 			
 			Local ax=EntityPitch(True)
 			Local ay=EntityYaw(True)
 			Local az=EntityRoll(True)
 						
-			Local new_mat:TMatrix=New TMatrix
+			Local new_mat:TMatrix=_gFactory.generateMatrix()
 			new_mat.LoadIdentity()
 			new_mat.Rotate(-ax,-ay,-az)
 			new_mat.Translate(px,py,pz)
 
 			px=new_mat.grid[3,0]
 			py=new_mat.grid[3,1]
 			pz=new_mat.grid[3,2]
 
 		EndIf
 	
@@ -483,21 +546,21 @@
 		UpdateChildren(Self)
 
 	End Method
 	
 	Method MoveEntity(x#,y#,z#)
 
 		Local mx#=x
 		Local my#=y
 		Local mz#=-z
 
-		Local new_mat:TMatrix=New TMatrix
+		Local new_mat:TMatrix=_gFactory.generateMatrix()
 		new_mat.LoadIdentity()
 		new_mat.Rotate(rx,ry,rz)
 		new_mat.Translate(mx#,my#,mz#)
 	
 		mx=new_mat.grid[3,0]
 		my=new_mat.grid[3,1]
 		mz=new_mat.grid[3,2]
 		
 		px=px+mx
 		py=py+my
@@ -526,21 +589,21 @@
 		Local ty#=y
 		Local tz#=-z
 
 		' conv glob to local. x/y/z always local to parent or global if no parent
 		If glob=True And parent<>Null
 
 			Local xa=parent.EntityPitch(True)
 			Local ya=parent.EntityYaw(True)
 			Local za=parent.EntityRoll(True)
 						
-			Local new_mat:TMatrix=New TMatrix
+			Local new_mat:TMatrix=_gFactory.generateMatrix()
 			new_mat.LoadIdentity()
 			new_mat.Rotate(-xa,-ya,-za)
 			new_mat.Translate(tx,ty,tz)
 
 			tx=new_mat.grid[3,0]
 			ty=new_mat.grid[3,1]
 			tz=new_mat.grid[3,2]
 			
 		EndIf
 		
@@ -646,21 +709,21 @@
 
 		' conv glob to local. x/y/z always local to parent or global if no parent
 		If glob=True And parent<>Null
 
 			'***todo*** 28/04/06 turnentity global - 'true rotations' - quarts?
 			Rem
 			Local xa=parent.EntityPitch(True)
 			Local ya=parent.EntityYaw(True)
 			Local za=parent.EntityRoll(True)
 						
-			Local new_mat:TMatrix=New TMatrix
+			Local new_mat:TMatrix=_gFactory.generateMatrix()
 			new_mat.LoadIdentity()
 			new_mat.Rotate(-xa,-ya,-za)
 			new_mat.Translate(tx,ty,tz)
 
 			tx=new_mat.grid[3,0]
 			ty=new_mat.grid[3,1]
 			tz=new_mat.grid[3,2]
 			End Rem
 			
 		EndIf
@@ -1275,21 +1338,21 @@
 	
 	Field fog_mode
 	Field fog_r#,fog_g#,fog_b#
 	Field fog_range_near#=1.0,fog_range_far#=1000.0
 	
 	Field frustum#[6,4]
 	
 	Method CopyEntity:TCamera(parent_ent:TEntity=Null)
 
 		' new cam, add parent, add to list
-		Local cam:TCamera=New TCamera
+		Local cam:TCamera=_gFactory.generateCamera()
 		cam.AddParent(parent_ent:TEntity)
 		cam.EntityListAdd(entity_list)
 		
 		' update matrix
 		If cam.parent<>Null
 			cam.mat.Overwrite(cam.parent.mat)
 		Else
 			cam.mat.LoadIdentity()
 		EndIf
 		
@@ -1351,21 +1414,21 @@
 	Method FreeEntity()
 	
 		Super.FreeEntity() 
 		
 		ListRemove cam_list,Self
 		
 	End Method
 
 	Function CreateCamera:TCamera(parent_ent:TEntity=Null)
 
-		Local cam:TCamera=New TCamera
+		Local cam:TCamera=_gFactory.generateCamera()
 		
 		CameraViewport cam,0,0,TGlobal.width,TGlobal.height
 		
 		cam.class$="CAMERA"
 		
 		cam.AddParent(parent_ent:TEntity)
 		cam.EntityListAdd(entity_list) ' add to entity list
 		cam.EntityListAdd(cam_list) ' add to cam list
 		
 		' update matrix
@@ -1618,21 +1681,21 @@
 		EndIf
 					
 		glMatrixMode(GL_PROJECTION)
 		glLoadIdentity()
 		Local ratio#=(Float(vwidth)/vheight)
 		gluPerspective(ATan((1.0/(zoom#*ratio#)))*2.0,ratio#,range_near#,range_far#)
 		'gluPerspective(90.0,1.0,range_near#,range_far#)
 				
 		glMatrixMode(GL_MODELVIEW)
 		
-		Local new_mat:TMatrix=New TMatrix
+		Local new_mat:TMatrix=_gFactory.generateMatrix()
 		new_mat=MatInverse:TMatrix(mat)	
 		glLoadMatrixf(new_mat.grid)
 		
 		ExtractFrustum()
 																																																																																																																																																																																																																																																						
 	End Method		
 		
 End Type
 
 Type TLight Extends TEntity
@@ -1647,21 +1710,21 @@
 	Global light_list:TList=CreateList()
 
 	Field light_type=0
 	Field range#=1.0/1000.0
 	Field red#=1.0,green#=1.0,blue#=1.0
 	Field inner_ang#=0.0,outer_ang#=45.0
 
 	Method CopyEntity:TLight(parent_ent:TEntity=Null)
 
 		' new light, add parent, add to list
-		Local light:TLight=New TLight
+		Local light:TLight=_gFactory.generateLight()
 		light.AddParent(parent_ent:TEntity)
 		light.EntityListAdd(entity_list)
 		
 		' update matrix
 		If light.parent<>Null
 			light.mat.Overwrite(light.parent.mat)
 		Else
 			light.mat.LoadIdentity()
 		EndIf
 		
@@ -1714,21 +1777,21 @@
 	Method FreeEntity()
 	
 		Super.FreeEntity() 
 		
 		ListRemove light_list,Self
 		
 	End Method
 	
 	Function CreateLight:TLight(l_type=1,parent_ent:TEntity=Null)
 
-		Local light:TLight=New TLight
+		Local light:TLight=_gFactory.generateLight()
 		light.light_type=l_type
 		light.class$="LIGHT"
 		
 		If no_lights=>max_lights Then Return ' no more lights available, return and gc will collect create light
 		
 		' no of lights increased, enable additional gl light
 		no_lights=no_lights+1
 		glEnable(gl_light[no_lights-1])
 		
 		Local white_light#[]=[1.0,1.0,1.0,1.0]
@@ -1833,21 +1896,21 @@
 																	
 	End Method		
 		
 End Type
 
 Type TPivot Extends TEntity
 
 	Method CopyEntity:TPivot(parent_ent:TEntity=Null)
 
 		' new piv, add parent, add to list
-		Local piv:TPivot=New TPivot
+		Local piv:TPivot=_gFactory.generatePivot()
 		piv.AddParent(parent_ent:TEntity)
 		piv.EntityListAdd(entity_list)
 		
 		' update matrix
 		If piv.parent<>Null
 			piv.mat.Overwrite(piv.parent.mat)
 		Else
 			piv.mat.LoadIdentity()
 		EndIf
 		
@@ -1886,21 +1949,21 @@
 	End Method
 	
 	Method FreeEntity()
 	
 		Super.FreeEntity() 
 			
 	End Method
 	
 	Function CreatePivot:TPivot(parent_ent:TEntity=Null)
 
-		Local piv:TPivot=New TPivot
+		Local piv:TPivot=_gFactory.generatePivot()
 		piv.class$="PIVOT"
 		
 		piv.AddParent(parent_ent:TEntity)
 		piv.EntityListAdd(entity_list)
 
 		' update matrix
 		If piv.parent<>Null
 			piv.mat.Overwrite(piv.parent.mat)
 			piv.UpdateMat()
 		Else
@@ -1920,28 +1983,28 @@
 End Type
 
 Type TMesh Extends TEntity
 	
 	Field surf_list:TList=CreateList()
 	Field anim_surf_list:TList=CreateList() ' only used if mesh contains anim info, only contains vertex coords array, initialised upon loading b3d
 	Field no_surfs=0
 	
 	Field bone_list:TList=CreateList()
 	
-	Field mat_sp:TMatrix=New TMatrix ' mat_sp used in TMesh's Update to provide necessary additional transform matrix for sprites
+	Field mat_sp:TMatrix=_gFactory.generateMatrix() ' mat_sp used in TMesh's Update to provide necessary additional transform matrix for sprites
 	
 	'Field aorder
 	
 	Method CopyEntity:TMesh(parent_ent:TEntity=Null)
 
 		' new mesh, add parent, add to list
-		Local mesh:TMesh=New TMesh
+		Local mesh:TMesh=_gFactory.generateMesh()
 		mesh.AddParent(parent_ent:TEntity)
 		mesh.EntityListAdd(entity_list)
 		
 		' update matrix
 		If mesh.parent<>Null
 			mesh.mat.Overwrite(mesh.parent.mat)
 		Else
 			mesh.mat.LoadIdentity()
 		EndIf
 		
@@ -1988,21 +2051,21 @@
 		mesh.no_seqs=no_seqs
 		mesh.anim_update=anim_update
 	
 		' copy mesh info
 		
 		' pointer to surf list
 		mesh.surf_list=surf_list
 		
 		' copy anim surf list
 		For Local surf:TSurface=EachIn anim_surf_list
-			Local new_surf:TSurface=New TSurface
+			Local new_surf:TSurface=_gFactory.generateSurface()
 			new_surf.vert_coords#=surf.vert_coords#[..]
 			ListAddLast(mesh.anim_surf_list,new_surf)
 		Next
 		
 		mesh.no_surfs=no_surfs
 		
 		CopyBonesList(mesh,mesh.bone_list)
 
 		Return mesh
 
@@ -2013,21 +2076,21 @@
 		Super.FreeEntity() 
 		
 		'ClearList surf_list
 		ClearList anim_surf_list
 		ClearList bone_list
 		
 	End Method
 	
 	Function CreateMesh:TMesh(parent_ent:TEntity=Null)
 
-		Local mesh:TMesh=New TMesh
+		Local mesh:TMesh=_gFactory.generateMesh()
 		'mesh.InitEntity("MESH",parent_ent)
 
 		mesh.class$="MESH"
 		
 		mesh.AddParent(parent_ent:TEntity)
 		mesh.EntityListAdd(entity_list)
 
 		' update matrix
 		If mesh.parent<>Null
 			mesh.mat.Overwrite(mesh.parent.mat)
@@ -2662,21 +2725,21 @@
 			Next
 		
 		Next
 	
 	EndMethod
 	
 	Method PaintMesh(bru:TBrush)
 	
 		For Local surf:TSurface=EachIn surf_list
 		
-			If surf.brush=Null Then surf.brush=New TBrush
+			If surf.brush=Null Then surf.brush=_gFactory.generateBrush()
 			
 			surf.brush.no_texs=bru.no_texs
 			surf.brush.name$=bru.name$
 			surf.brush.red#=bru.red#
 			surf.brush.green#=bru.green#
 			surf.brush.blue#=bru.blue#
 			surf.brush.alpha#=bru.alpha#
 			surf.brush.shine#=bru.shine#
 			surf.brush.blend=bru.blend
 			surf.brush.fx=bru.fx
@@ -2743,43 +2806,43 @@
 				surf.VertexCoords(v,vx#,vy#,vz#)
 
 			Next
 							
 		Next
 	
 	End Method
 	
 	Method ScaleMesh(sx#,sy#,sz#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 		mat.LoadIdentity()
 		mat.Scale(sx#,sy#,sz#)
 	
 		TransformMesh(mat)
 
 	End Method
 	
 	Method RotateMesh(pitch#,yaw#,roll#)
 	
 		pitch#=-pitch#
 		
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 		mat.LoadIdentity()
 		mat.Rotate(pitch#,yaw#,roll#)
 	
 		TransformMesh(mat)
 		
 	End Method
 	
 	Method PositionMesh(px#,py#,pz#)
 
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 		mat.LoadIdentity()
 		mat.Translate(px#,py#,-pz#) ' ***ogl***
 	
 		TransformMesh(mat)
 
 	End Method
 		
 	' unoptimised, unused, used for understanding purposes only
 	Method UpdateNormals0()
 
@@ -2909,21 +2972,21 @@
 			Next
 							
 		Next
 		
 		'DebugLog MilliSecs()-ms
 		
 	End Method
 	
 	Method CreateSurface:TSurface(bru:TBrush=Null)
 	
-		Local surf:TSurface=New TSurface
+		Local surf:TSurface=_gFactory.generateSurface()
 		ListAddLast surf_list,surf
 		
 		no_surfs=no_surfs+1
 		
 		surf.brush=bru
 		
 		Return surf
 		
 	End Method
 	
@@ -3031,41 +3094,41 @@
 		Next
 		
 		Return Null
 	
 	End Method
 
 	' Helper funcs
 	
 	Method CollapseAnimMesh:TMesh(mesh:TMesh=Null)
 	
-		If mesh=Null Then mesh=New TMesh
+		If mesh=Null Then mesh=_gFactory.generateMesh()
 		
 		If TMesh(Self)<>Null
-			Local new_mesh:TMesh=New TMesh 'TMesh(ent).CopyMesh() ' don't use copymesh, uses CreateMesh and adds to entity list
+			Local new_mesh:TMesh=_gFactory.generateMesh() 'TMesh(ent).CopyMesh() ' don't use copymesh, uses CreateMesh and adds to entity list
 			TMesh(Self).AddMesh(new_mesh)
 			new_mesh.TransformMesh(Self.mat)
 			new_mesh.AddMesh(mesh)
 		EndIf
 		
 		mesh=CollapseChildren(Self,mesh)
 
 		Return mesh
 
 	End Method
 	
 	' has to be function as we need to use this function with all entities and not just meshes
 	Function CollapseChildren:TMesh(ent0:TEntity,mesh:TMesh=Null)
 
 		For Local ent:TEntity=EachIn ent0.child_list
 			If TMesh(ent)<>Null
-				Local new_mesh:TMesh=New TMesh 'TMesh(ent).CopyMesh() ' don't use copymesh, uses CreateMesh and adds to entity list
+				Local new_mesh:TMesh=_gFactory.generateMesh() 'TMesh(ent).CopyMesh() ' don't use copymesh, uses CreateMesh and adds to entity list
 				TMesh(ent).AddMesh(new_mesh)
 				new_mesh.TransformMesh(ent.mat)
 				new_mesh.AddMesh(mesh)
 			EndIf
 			mesh=CollapseChildren(ent,mesh)
 		Next
 		
 		Return mesh
 		
 	End Function
@@ -3486,29 +3549,29 @@
 
 End Type
 
 Type TSprite Extends TMesh
 
 	Field angle#
 	Field x_scale#=1.0,y_scale#=1.0
 	Field x_handle#,y_handle# 
 	Field view_mode=1
 	
-	Field vPoint0:TVector=New TVector
-	Field vPoint1:TVector=New TVector
-	Field vPoint2:TVector=New TVector
-	Field vPoint3:TVector=New TVector
+	Field vPoint0:TVector=_gFactory.generateVector()
+	Field vPoint1:TVector=_gFactory.generateVector()
+	Field vPoint2:TVector=_gFactory.generateVector()
+	Field vPoint3:TVector=_gFactory.generateVector()
 
 	Method CopyEntity:TSprite(parent_ent:TEntity)
 	
 		' new sprite, add parent, add to list
-		Local sprite:TSprite=New TSprite
+		Local sprite:TSprite=_gFactory.generateSprite()
 		sprite.AddParent(parent_ent:TEntity)
 		sprite.EntityListAdd(entity_list)
 		
 		' update matrix
 		If sprite.parent<>Null
 			sprite.mat.Overwrite(sprite.parent.mat)
 		Else
 			sprite.mat.LoadIdentity()
 		EndIf
 		
@@ -3555,21 +3618,21 @@
 		sprite.no_seqs=no_seqs
 		sprite.anim_update=anim_update
 	
 		' copy mesh info
 		
 		' pointer to surf list
 		sprite.surf_list=surf_list
 		
 		' copy anim surf list
 		For Local surf:TSurface=EachIn anim_surf_list
-			Local new_surf:TSurface=New TSurface
+			Local new_surf:TSurface=_gFactory.generateSurface()
 			new_surf.vert_coords#=surf.vert_coords#[..]
 			ListAddLast(sprite.anim_surf_list,new_surf)
 		Next
 		
 		sprite.no_surfs=no_surfs
 		
 		CopyBonesList(sprite,sprite.bone_list)
 
 		' copy sprite info
 		
@@ -3580,21 +3643,21 @@
 		sprite.x_handle#=x_handle#
 		sprite.y_handle#=y_handle#
 		sprite.view_mode=view_mode
 
 		Return sprite
 	
 	End Method
 
 	Function CreateSprite:TSprite(parent_ent:TEntity=Null)
 
-		Local sprite:TSprite=New TSprite
+		Local sprite:TSprite=_gFactory.generateSprite()
 		sprite.class$="SPRITE"
 		
 		sprite.AddParent(parent_ent:TEntity)
 		sprite.EntityListAdd(entity_list)
 
 		' update matrix
 		If sprite.parent<>Null
 			sprite.mat.Overwrite(sprite.parent.mat)
 			sprite.UpdateMat()
 		Else
@@ -3665,21 +3728,21 @@
 
 	Field keys:TKeys
 	
 	Field inv_mat:TMatrix
 	
 	Field kx#,ky#,kz#,kqw#,kqx#,kqy#,kqz# ' used to store current keyframe in AnimateMesh, for use with transition
 	
 	Method CopyEntity:TBone(parent_ent:TEntity=Null)
 	
 		' new bone, add parent, add to list
-		Local bone:TBone=New TBone
+		Local bone:TBone=_gFactory.generateBone()
 		bone.AddParent(parent_ent:TEntity)
 		bone.EntityListAdd(entity_list)
 		
 		' update matrix
 		If bone.parent<>Null
 			bone.mat.Overwrite(bone.parent.mat)
 		Else
 			bone.mat.LoadIdentity()
 		EndIf
 		
@@ -3784,21 +3847,21 @@
 	
 	' misc vars
 	
 	Field vert_array_size=1
 	Field tri_array_size=1
 	Field vmin=1000000 ' used for animation - seeb3dloader (tris)
 	Field vmax=0 ' used for animation - see b3dloader (tris)
 					
 	Method Copy:TSurface()
 	
-		Local surf:TSurface=New TSurface
+		Local surf:TSurface=_gFactory.generateSurface()
 		
 		surf.no_verts=no_verts
 		surf.no_tris=no_tris
 		
 		surf.tris=tris[..]
 		surf.vert_coords#=vert_coords#[..]
 		surf.vert_tex_coords0#=vert_tex_coords0#[..]
 		surf.vert_tex_coords1#=vert_tex_coords1#[..]
 		surf.vert_norm#=vert_norm[..]
 		surf.vert_col#=vert_col[..]
@@ -4155,21 +4218,21 @@
 	Method FreeTexture()
 	
 		ListRemove(tex_list,Self)
 		pixmap=Null
 		gltex=Null
 	
 	End Method
 	
 	Function LoadTexture:TTexture(file$,flags=1)
 	
-		Local tex:TTexture=New TTexture
+		Local tex:TTexture=_gFactory.generateTexture()
 		If FileType(file$)=0
 			Repeat
 				file$=Right$(file$,(Len(file$)-Instr(file$,"",1)))
 			Until Instr(file$,"",1)=0
 			Repeat
 				file$=Right$(file$,(Len(file$)-Instr(file$,"/",1)))
 			Until Instr(file$,"/",1)=0
 			If FileType(file$)=0
 				DebugLog "ERROR: Cannot find texture: "+file$
 				Return Null
@@ -4302,41 +4365,41 @@
 	End Method
 	
 	Function ClearTextureFilters()
 	
 		ClearList TTextureFilter.filter_list
 	
 	End Function
 	
 	Function TextureFilter(match_text$,flags)
 	
-		Local filter:TTextureFilter=New TTextureFilter
+		Local filter:TTextureFilter=_gFactory.generateTextureFilter()
 		filter.text$=match_text$
 		filter.flags=flags
 		ListAddLast(TTextureFilter.filter_list,filter)
 	
 	End Function
 
 End Type
 
 Type TBrush
 
 	Field no_texs
 	Field name$
 	Field red#=1.0,green#=1.0,blue#=1.0,alpha#=1.0
 	Field shine#
 	Field blend,fx
 	Field tex:TTexture[8]
 	
 	Method Copy:TBrush()
 		
-		Local brush:TBrush=New TBrush
+		Local brush:TBrush=_gFactory.generateBrush()
 	
 		brush.no_texs=no_texs
 		brush.name$=name$
 		brush.red#=red#
 		brush.green#=green#
 		brush.blue#=blue#
 		brush.alpha#=alpha#
 		brush.shine#=shine#
 		brush.blend=blend
 		brush.fx=fx
@@ -4352,32 +4415,32 @@
 		Return brush
 
 	End Method
 	
 	Method FreeBrush()
 	
 	End Method
 		
 	Function CreateBrush:TBrush(r#=255.0,g#=255.0,b#=255.0)
 	
-		Local brush:TBrush=New TBrush
+		Local brush:TBrush=_gFactory.generateBrush()
 		brush.red#=r#/255.0
 		brush.green#=g#/255.0
 		brush.blue#=b#/255.0
 		
 		Return brush
 		
 	End Function
 	
 	Function LoadBrush:TBrush(file$,flags=1,u_scale#=1.0,v_scale#=1.0)
 	
-		Local brush:TBrush=New TBrush
+		Local brush:TBrush=_gFactory.generateBrush()
 		brush.tex[0]=TTexture.LoadTexture:TTexture(file$,flags)
 		brush.no_texs=1
 		'brush.tex[0].u_scale#=u_scale#
 		'brush.tex[0].v_scale#=v_scale#
 				
 		Return brush
 		
 	End Function
 	
 	Method BrushColor(r#,g#,b#)
@@ -4475,21 +4538,21 @@
 		grid[0,3]=0.0
 		grid[1,3]=0.0
 		grid[2,3]=0.0
 		grid[3,3]=1.0
 	
 	End Method
 	
 	' unoptimised, unused, used for understanding purposes only
 	Method Multiply0(mat:TMatrix)
 	
-		Local new_mat:TMatrix=New TMatrix
+		Local new_mat:TMatrix=_gFactory.generateMatrix()
 	
 		Local sum#=0
 	
 		Local row=0
 		Local col=0
 	
 		For row=0 To 3
 			For col=0 To 3
 				For Local r=0 To 3
 					Local a#=grid#[r,col]
@@ -4546,21 +4609,21 @@
 		grid[3,1]=m31
 		grid[3,2]=m32
 		'grid[3,3]=m33
 		
 	End Method
 	
 	' copy - create new copy and returns it
 	
 	Method Copy:TMatrix()
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=grid[0,0]
 		mat.grid[1,0]=grid[1,0]
 		mat.grid[2,0]=grid[2,0]
 		mat.grid[3,0]=grid[3,0]
 		mat.grid[0,1]=grid[0,1]
 		mat.grid[1,1]=grid[1,1]
 		mat.grid[2,1]=grid[2,1]
 		mat.grid[3,1]=grid[3,1]
 		mat.grid[0,2]=grid[0,2]
@@ -4598,21 +4661,21 @@
 		grid[0,3]=mat.grid[0,3]
 		grid[1,3]=mat.grid[1,3]
 		grid[2,3]=mat.grid[2,3]
 		grid[3,3]=mat.grid[3,3]
 		
 	End Method
 	
 	' unoptimised, unused, used for understanding purposes only
 	Method Translate0(x#,y#,z#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=1
 		mat.grid[1,0]=0
 		mat.grid[2,0]=0
 		mat.grid[3,0]=x#
 		mat.grid[0,1]=0
 		mat.grid[1,1]=1
 		mat.grid[2,1]=0
 		mat.grid[3,1]=y#
 		mat.grid[0,2]=0
@@ -4634,21 +4697,21 @@
 	
 		grid[3,0] = grid#[0,0]*x# + grid#[1,0]*y# + grid#[2,0]*z# + grid#[3,0]
 		grid[3,1] = grid#[0,1]*x# + grid#[1,1]*y# + grid#[2,1]*z# + grid#[3,1]
 		grid[3,2] = grid#[0,2]*x# + grid#[1,2]*y# + grid#[2,2]*z# + grid#[3,2]
 
 	End Method
 		
 	' unoptimised, unused, used for understanding purposes only
 	Method Scale0(x#,y#,z#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=x#
 		mat.grid[1,0]=0
 		mat.grid[2,0]=0
 		mat.grid[3,0]=0
 		mat.grid[0,1]=0
 		mat.grid[1,1]=y#
 		mat.grid[2,1]=0
 		mat.grid[3,1]=0
 		mat.grid[0,2]=0
@@ -4710,21 +4773,21 @@
 	
 		RotateRoll(az#)
 		RotatePitch(ax#)
 		RotateYaw(ay#)
 		
 	End Method
 	
 	' unoptimised, unused, used for understanding purposes only
 	Method RotatePitch0(ang#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=1
 		mat.grid[1,0]=0
 		mat.grid[2,0]=0
 		mat.grid[3,0]=0
 		mat.grid[0,1]=0
 		mat.grid[1,1]=Cos(ang#)
 		mat.grid[2,1]=-Sin(ang#)
 		mat.grid[3,1]=0
 		mat.grid[0,2]=0
@@ -4757,21 +4820,21 @@
 
 		grid[1,0]=m10
 		grid[1,1]=m11
 		grid[1,2]=m12
 
 	End Method
 	
 	' unoptimised, unused, used for understanding purposes only
 	Method RotateYaw0(ang#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=Cos(ang#)
 		mat.grid[1,0]=0
 		mat.grid[2,0]=Sin(ang#)
 		mat.grid[3,0]=0
 		mat.grid[0,1]=0
 		mat.grid[1,1]=1
 		mat.grid[2,1]=0
 		mat.grid[3,1]=0
 		mat.grid[0,2]=-Sin(ang#)
@@ -4804,21 +4867,21 @@
 
 		grid[0,0]=m00#
 		grid[0,1]=m01#
 		grid[0,2]=m02#
 
 	End Method
 	
 	' unoptimised, unused, used for understanding purposes only
 	Method RotateRoll0(ang#)
 	
-		Local mat:TMatrix=New TMatrix
+		Local mat:TMatrix=_gFactory.generateMatrix()
 	
 		mat.grid[0,0]=Cos(ang#)
 		mat.grid[1,0]=-Sin(ang#)
 		mat.grid[2,0]=0
 		mat.grid[3,0]=0
 		mat.grid[0,1]=Sin(ang#)
 		mat.grid[1,1]=Cos(ang#)
 		mat.grid[2,1]=0
 		mat.grid[3,1]=0
 		mat.grid[0,2]=0
@@ -4877,64 +4940,64 @@
 	
 		Local d#=1/Sqr(x*x+y*y+z*z)
 		x:*d
 		y:*d
 		z:*d
 		
 	End Method
 	
 	Function Create:TVector( x#,y#,z# )
 	
-		Local vec:TVector=New TVector
+		Local vec:TVector=_gFactory.generateVector()
 		vec.x=x
 		vec.y=y
 		vec.z=z
 		
 		Return vec
 		
 	End Function
 	
 	Method Equals(vec:TVector)
 	
 		x=vec.x
 		y=vec.y
 		z=vec.z
 		
 	End Method
 	
 	Method Add:TVector(vec:TVector)
 	
-		Local new_vec:TVector=New TVector
+		Local new_vec:TVector=_gFactory.generateVector()
 		
 		new_vec.x=x+vec.x
 		new_vec.y=y+vec.y
 		new_vec.z=z+vec.z
 		
 		Return new_vec
 	
 	End Method
 	
 	Method Subtract:TVector(vec:TVector)
 	
-		Local new_vec:TVector=New TVector
+		Local new_vec:TVector=_gFactory.generateVector()
 		
 		new_vec.x=x-vec.x
 		new_vec.y=y-vec.y
 		new_vec.z=z-vec.z
 		
 		Return new_vec
 	
 	End Method
 	
 	Method Multiply:TVector(val#)
 	
-		Local new_vec:TVector=New TVector
+		Local new_vec:TVector=_gFactory.generateVector()
 		
 		new_vec.x=x*val#
 		new_vec.y=y*val#
 		new_vec.z=z*val#
 		
 		Return new_vec
 	
 	End Method
 	
 	Method Dot:TVector(vec:TVector)
@@ -4964,21 +5027,21 @@
 	Field sx#[1]
 	Field sy#[1]
 	Field sz#[1]
 	Field qw#[1]
 	Field qx#[1]
 	Field qy#[1]
 	Field qz#[1]
 	
 	Method Copy:TKeys()
 	
-		Local keys:TKeys=New TKeys
+		Local keys:TKeys=_gFactory.generateKeys()
 	
 		keys.frames=frames
 		keys.flags=flags[..]
 		keys.px#=px#[..]
 		keys.py#=py#[..]
 		keys.pz#=pz#[..]
 		keys.sx#=sx#[..]
 		keys.sy#=sy#[..]
 		keys.sz#=sz#[..]
 		keys.qw#=qw#[..]
@@ -5372,21 +5435,21 @@
 				QuatToEuler(-n_qw#,n_qx#,n_qy#,-n_qz#,pitch#,yaw#,roll#)
 				n_rx#=-pitch#
 				n_ry#=yaw#
 				n_rz#=roll#
 
 				new_tag$=ReadTag$(file)
 				
 				If new_tag$="NODE" Or new_tag$="ANIM"
 	
 					' make 'piv' entity a mesh, not a pivot, as B3D does
-					Local piv:TMesh=New TMesh
+					Local piv:TMesh=_gFactory.generateMesh()
 					piv.class$="MESH"
 		
 					piv.name$=n_name$
 					piv.px#=n_px#
 					piv.py#=n_py#
 					piv.pz#=n_pz#
 					piv.sx#=n_sx#
 					piv.sy#=n_sy#
 					piv.sz#=n_sz#
 					piv.rx#=n_rx#
@@ -5421,21 +5484,21 @@
 						new_mat.Multiply(piv.mat)
 						piv.mat.Overwrite(new_mat)'.Multiply(mat)
 					EndIf				
 			
 				EndIf
 		
 			Case "MESH"
 					
 				m_brush_id=ReadInt(file)
 				
-				mesh=New TMesh
+				mesh=_gFactory.generateMesh()
 				mesh.class$="MESH"
 				mesh.name$=n_name$
 				mesh.px#=n_px#
 				mesh.py#=n_py#
 				mesh.pz#=n_pz#
 				mesh.sx#=n_sx#
 				mesh.sy#=n_sy#
 				mesh.sz#=n_sz#
 				mesh.rx#=n_rx#
 				mesh.ry#=n_ry#
@@ -5467,21 +5530,21 @@
 					Local new_mat:TMatrix=mesh.parent.mat.Copy()
 					new_mat.Multiply(mesh.mat)
 					mesh.mat.Overwrite(new_mat)'.Multiply(mat)
 				EndIf				
 
 			Case "VRTS"
 			
 				If v_mesh<>Null Then v_mesh=Null
 				If v_surf<>Null Then v_surf=Null
 					
-				v_mesh=New TMesh
+				v_mesh=_gFactory.generateMesh()
 				v_surf=v_mesh.CreateSurface()
 				v_flags=ReadInt(file)
 				v_tc_sets=ReadInt(file)
 				v_tc_size=ReadInt(file)
 				v_sz=12+v_tc_sets*v_tc_size*4
 				If v_flags & 1 Then v_sz=v_sz+12
 				If v_flags & 2 Then v_sz=v_sz+16
 
 				new_tag$=ReadTag$(file)
 
@@ -5589,21 +5652,21 @@
 				If mesh<>Null
 				
 					mesh.anim=True
 				
 					'mesh.frames=a_frames
 					mesh.anim_seqs_first[0]=0
 					mesh.anim_seqs_last[0]=a_frames
 					
 					' create anim surfs, copy vertex coords array, add to anim_surf_list
 					For Local surf:TSurface=EachIn mesh.surf_list
-						Local anim_surf:TSurface=New TSurface
+						Local anim_surf:TSurface=_gFactory.generateSurface()
 						anim_surf.vert_coords=surf.vert_coords[..]
 						ListAddLast(mesh.anim_surf_list,anim_surf)
 					Next
 					
 					'mesh.verts_w=mesh.verts_w[..v_surf.no_verts]
 					'mesh.verts_w1#=mesh.verts_w1#[..v_surf.no_verts]
 					'mesh.verts_w2#=mesh.verts_w2#[..v_surf.no_verts]
 					'mesh.verts_w3#=mesh.verts_w3#[..v_surf.no_verts]
 					'mesh.verts_w4#=mesh.verts_w4#[..v_surf.no_verts]
 					
@@ -5627,21 +5690,21 @@
 
 					bo_no_verts=bo_no_verts+1
 					
 					bo_verts_id=bo_verts_id[..bo_no_verts+1]
 					bo_verts_w#=bo_verts_w#[..bo_no_verts+1]
 
 					new_tag$=ReadTag$(file)
 						
 				Wend
 				
-				bo_bone:TBone=New TBone
+				bo_bone:TBone=_gFactory.generateBone()
 				
 				'bo_bone.mesh=mesh				
 				
 				bo_bone.no_verts=bo_no_verts
 				bo_bone.verts_id=bo_verts_id[..]
 				bo_bone.verts_w#=bo_verts_w#[..]
 				
 				bo_bone.class$="BONE"
 				bo_bone.name$=n_name$
 				bo_bone.px#=n_px#
@@ -5665,21 +5728,21 @@
 				bo_bone.n_sy#=n_sy#
 				bo_bone.n_sz#=n_sz#
 				bo_bone.n_rx#=n_rx#
 				bo_bone.n_ry#=n_ry#
 				bo_bone.n_rz#=n_rz#
 				bo_bone.n_qw#=n_qw#
 				bo_bone.n_qx#=n_qx#
 				bo_bone.n_qy#=n_qy#
 				bo_bone.n_qz#=n_qz#
 			
-				bo_bone.keys=New TKeys
+				bo_bone.keys=_gFactory.generateKeys()
 				bo_bone.keys.frames=a_frames
 				bo_bone.keys.flags=bo_bone.keys.flags[..a_frames+1]
 				bo_bone.keys.px=bo_bone.keys.px[..a_frames+1]
 				bo_bone.keys.py=bo_bone.keys.py[..a_frames+1]
 				bo_bone.keys.pz=bo_bone.keys.pz[..a_frames+1]
 				bo_bone.keys.sx=bo_bone.keys.sx[..a_frames+1]
 				bo_bone.keys.sy=bo_bone.keys.sy[..a_frames+1]
 				bo_bone.keys.sz=bo_bone.keys.sz[..a_frames+1]
 				bo_bone.keys.qw=bo_bone.keys.qw[..a_frames+1]
 				bo_bone.keys.qx=bo_bone.keys.qx[..a_frames+1]
@@ -6424,21 +6487,21 @@
 	
 End Function
 
 ' Maths helper funcs
 
 Function o___________________________o()
 End Function
 
 Function MatInverse:TMatrix( mat:TMatrix )
 
-	Local new_mat:TMatrix=New TMatrix
+	Local new_mat:TMatrix=_gFactory.generateMatrix()
 
 	Local tx#=0
 	Local ty#=0
 	Local tz#=0
 
   	' The rotational part of the matrix is simply the transpose of the
   	' original matrix.
   	new_mat.grid[0,0] = mat.grid[0,0]
   	new_mat.grid[1,0] = mat.grid[0,1]
   	new_mat.grid[2,0] = mat.grid[0,2]
@@ -6524,21 +6587,21 @@
 	Local xx#=q[1]*q[1]
 	Local yy#=q[2]*q[2]
 	Local zz#=q[3]*q[3]
 	Local xy#=q[1]*q[2]
 	Local xz#=q[1]*q[3]
 	Local yz#=q[2]*q[3]
 	Local wx#=q[0]*q[1]
 	Local wy#=q[0]*q[2]
 	Local wz#=q[0]*q[3]
 
-	Local mat:TMatrix=New TMatrix
+	Local mat:TMatrix=_gFactory.generateMatrix()
 	
 	mat.grid[0,0]=1-2*(yy+zz)
 	mat.grid[0,1]=  2*(xy-wz)
 	mat.grid[0,2]=  2*(xz+wy)
 	mat.grid[1,0]=  2*(xy+wz)
 	mat.grid[1,1]=1-2*(xx+zz)
 	mat.grid[1,2]=  2*(yz-wx)
 	mat.grid[2,0]=  2*(xz-wy)
 	mat.grid[2,1]=  2*(yz+wx)
 	mat.grid[2,2]=1-2*(xx+yy)


Blimey, that's a lot of effort. Is anyone really going to go to that much trouble to update MiniB3D?

Maybe I can write a small app to automate the process. Thanks for going to the touble of writing the tutorial.

What's wrong with just using Subversion?

Subversion is right below this :)
Updates still should be done with patches, though. They're quite neat little things, and easy enough if you have a working SVN GUI or a decent text console.