Multi types and functions

Blitz3D Forums/Blitz3D Programming/Multi types and functions

Shifty Geezer(Posted 2005) [#1]
I'm having a headache with types and functions. I've two types, one referencing the other

Type material
	Field index
	Field density#
	Field friction#
	Field restitution#
End Type
Type ODE_object
	Field body
	Field geom
	Field mesh
	Field mat.material
End Type
I've an array of ODE_objects...

Dim objects.ODE_object(200)
For n=0 To 200
	objects(n) = New ODE_object
Next
And I've functions to fill them...

Function create_Box.ODE_object(x_pos, y_pos, z_pos, width, length, depth, x_rot, y_rot, z_rot)
	obj.ODE_object = New ODE_object
	obj\mat.material = New material
	blah blah
	Return obj
End Function

Function set_material(obj.ODE_object,m.material)
	obj\mat\index = m\index
	obj\mat\friction = m\friction
	obj\mat\density = m\density
	obj\mat\restitution = m\restitution
End Function
Trouble is when I try to reference objects(n)\mat I'm told the object doesnt exist (in this example at the statement i=objects(n)\mat\index)...

	set_material(objects(n),mat_ice)
	objects(n)=create_Box(Rnd(-40,40),100+Rnd(0,600),Rnd(-40,40), x,y,z, Rnd(-30,30),Rnd(-30,30),Rnd(-30,30))	

	i = objects(n)\mat\index
And if I create the object.mat object when I create the object.ODE_object, it still doesn't work because it gets overwritten when I return the ODE_object from the creation function.

How can I work my functions to create the necessary objects in a function and return them into the array of objects with all sub-objects intact?


RiverRatt(Posted 2005) [#2]
I don't do it the same way you are but have you tried returning the instance of the type, ie replace return obj with
something like return obj\mesh?
Anyhow this is how I do it, but I don't know if it will be what you want. Hope it helps.

for I = 1 to whatever
cill(i)=Make_OBJ(1,False,False,12,cill(i))
next



;in function
Function Make_OBJ(shape,par,sol,segm,obj)

Make.RB_OBJ=New RB_OBJ
 
 Make\parent=par
 Make\solid=sol
 Make\segments=segm
Select shape  
 	Case 1 ;Pill
        ;Makes the main body and the two spheres for end caps
		Make\obj=CreateCylinder(Make\segments,Make\solid,Make\parent)
		Local spheresegments=Make\segments/2
		t=CreateSphere(spheresegments,Make\obj)
		b=CreateSphere(spheresegments,Make\obj)

		 body.objscale=Last objscale
			;Scale the pill and position caps
			ScaleMesh Make\obj,body\x#,body\y#,body\z#
			ScaleMesh t,body\x#,body\y#,body\z#
 			PositionEntity t,0,body\y#,0
			ScaleEntity b,body\x#,body\y#,body\z#
			PositionEntity b,0,-body\y#,0
		  

		
		Return Make\obj




Shifty Geezer(Posted 2005) [#3]
Thanks for the idea. After a little thought I've found the most straight-forward approach is not to return an object at all, but pass the target in the parameters, so
Function create_Box.ODE_object(x_pos, y_pos, z_pos, width, length, depth, x_rot, y_rot, z_rot)
	obj.ODE_object = New ODE_object
	obj\mat.material = New material
	blah blah
	Return obj
End Function
becomes
Function create_Box(obj.ODE_object, x_pos, y_pos, z_pos, width, length, depth, x_rot, y_rot, z_rot)
	obj\mat.material = New material
	blah blah
End Function
I think I'm too 'classically trained' to automatically work with Blitz's ways!


big10p(Posted 2005) [#4]
Couple of things. First, you have:
Dim objects.ODE_object(200)
For n=0 To 200
	objects(n) = New ODE_object
Next

Which fills the array with blank ODE_object instances, but you then have:
	set_material(objects(n),mat_ice)
	objects(n)=create_Box(Rnd(-40,40),100+Rnd(0,600),Rnd(-40,40), x,y,z, Rnd(-30,30),Rnd(-30,30),Rnd(-30,30))	

	i = objects(n)\mat\index

Which is presumably inside a loop as you're using 'n' as an index. This fills the array again with ODE_objects, created and returned from the call to create_Box().

Also, in that code, you need to call set_material() after the call to create_Box().