Problems with type fields

BlitzMax Forums/BlitzMax Programming/Problems with type fields

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.


Isn't strict suppose to catch things like that?


you would think :) the reason it compiles in this case (i believe) is because you can store objects to integers.

As far as the B3D thing goes, I was aiming more at keeping the flexibility of the IrrLicht, but wrap the commands so that they're easier to call.


i think we are on similar targets. im taking the approach of many of the BRL BMAX modules where they have functions that can do many things, but underneath they are actually calling type methods. while i have a B3D function set, all the functions really do are call methods on types. you would never actually need to call a single ib3d function if you so desired. plus, all the underlying functionality is still there (ie. the entity stores the T_irrISceneNode reference, ib3d_engine stores references to all its corrosponding T_irr types) and you can call Irrlicht commands direct any time. for example, here is my entity Type of which all the ib3d entities are based:

Type ib3d_Entity Extends ib3d_base

	' maps a b3d entity to an ISceneNode
	Global SceneNodeToEntity:THashtable=Null
	Global EntityList:TList=Null

	Field _userdata:TMap=Null
	Field _node:T_irrISceneNode=Null
	Field _radius:T_irrVector3df=Null
	Field _collision_offset:T_irrVector3df=T_irrVector3df.create()
	Field _lastposition:T_irrVector3df=Null
	Field _OnCollision:ONCOLLISIONEVENTHANDLER=Null
			
	Method New()
		' setup the ISceneNode to b3d_entity map
		If Not SceneNodeToEntity Then SceneNodeToEntity=New THashtable
		If Not EntityList Then EntityList=New TList
		EntityList.AddLast(Self)
	EndMethod

	Method Destroy()
		SceneNodeToEntity.RemoveKey(_node.handle)
		EntityList.Remove(Self)
		
		If _userdata Then _userdata.Clear()
		
		' remove from the scene graph
		_node.Remove()
		_node=Null
	EndMethod

	Method setNode(node:T_irrISceneNode)
		If Not node.IsValid() Then RuntimeError "setNode is invalid"
		SceneNodeToEntity.Add(node.handle,Self,True)
		_node=node
		
		' set the initial collision radius based on the bounding box extents/2
		Local boxextent:T_irrVector3df=_node.getBoundingBox().getExtent()
		setCollisionRadius(boxextent.getX()/2,boxextent.getY()/2,boxextent.getZ()/2)		
	EndMethod
	
	Function findEntity:ib3d_entity(node:T_irrISceneNode)
		If Not node Or Not node.IsValid() Then Return Null
		Local temp:TKeyValuePair=SceneNodeToEntity.ContainsKey(node.handle)
		If Not temp Return Null Else Return ib3d_entity(temp.Value)
	EndFunction

	' ----------------------------------------------
	' userdata methods
	' ----------------------------------------------
	
	Method setUserData(key:String,data:Object)
		If Not _userdata Then _userdata=New TMap
		_userdata.Insert(key,data)
	EndMethod
	
	Method getUserData:Object(key:String)
		If _userdata Then Return _userdata.ValueForKey(key) Else Return Null
	EndMethod
	
	Method removeUserData(key:String)
		If _userdata Then _userdata.Remove(key)
	EndMethod		

	' ----------------------------------------------
	' collision support methods
	' ----------------------------------------------
	
	Method setCollisionOffset(offset:T_irrVector3df)
		_collision_offset=offset
	EndMethod
	
	Method setCollisionRadius(x:Float,y:Float,z:Float)
		_radius=T_irrVector3df.createFromVals(x,y,z)
	EndMethod
	
	Method setCollisionRadiusFromBox(box:T_irrAABbox3df)
		Local boxextent:T_irrVector3df=box.getExtent()
		setCollisionRadius(boxextent.getX()/2,boxextent.getY()/2,boxextent.getZ()/2)		
	EndMethod

	Method getCollisionRadius:T_irrVector3df()
		Return _radius
	EndMethod
	
	Method setOnCollisionEventHandler(handler:ONCOLLISIONEVENTHANDLER)
		_OnCollision=handler
	EndMethod
	
	Method OnCollision(collision:COLLISION)
		If _OnCollision Then _OnCollision.OnCollision(collision)
	EndMethod
	
	Method setLastPosition(pos:T_irrVector3df=Null)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If Not pos Then _lastposition=_node.getPosition() Else _lastposition=pos
	EndMethod
	
	Method getLastPosition:T_irrVector3df()
		Return _lastposition
	EndMethod
	
	' ---------------------------------------------------------------
	' B3D methods
	' ---------------------------------------------------------------
			
	Method X:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getPosition().getX()
		Else
			Return _node.getAbsolutePosition().getX()
		EndIf
	EndMethod

	Method Y:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getPosition().getY()
		Else
			Return _node.getAbsolutePosition().getY()
		EndIf
	EndMethod

	Method Z:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getPosition().getZ()
		Else
			Return _node.getAbsolutePosition().getZ()
		EndIf
	EndMethod

	Method Pitch:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getRotation().getX()
		Else
			Return _node.getAbsoluteTransformation().getRotationDegrees().getX()
		EndIf
	EndMethod

	Method Yaw:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getRotation().getY()
		Else
			Return _node.getAbsoluteTransformation().getRotationDegrees().getY()
		EndIf
	EndMethod

	Method Roll:Float(globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If (globl=False)
			Return _node.getRotation().getZ()
		Else
			Return _node.getAbsoluteTransformation().getRotationDegrees().getZ()
		EndIf
	EndMethod
	
	Method Scale(x:Float,y:Float,z:Float)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setScale(T_irrVector3df.createFromVals(x,y,z))
	EndMethod
	
	Method Show()
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setVisible(True)
	EndMethod
	
	Method Hide()
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setVisible(False)
	EndMethod

	Method Name(name:String)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setName(name)
	EndMethod
	
	Method GetName:String()
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Return _node.getName()
	EndMethod
	
	' TODO: implement globl param
	Method Parent(parent:ib3d_Entity,globl:Int=True)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setParent(parent._node)
	EndMethod
	
	Method GetParent:ib3d_Entity()
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Return findEntity(_node)
	EndMethod

	Method CountChildren:Int()
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Return _node.getChildren().Size()
	EndMethod
	
	Method GetChild:ib3d_Entity(index:Int)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local children:T_irrArray_ISceneNode_Ptr=_node.getChildren()
		Local childcnt:Int=children.Size()
		If childcnt<1 Or index>childcnt Then RuntimeError "Child index "+index+" outside of child count "+childcnt
	
		Return findEntity(children.elementAt(index-1))
	EndMethod
	
	Method FindChild:ib3d_Entity(name:String)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local child:T_irrISceneNode=Null
		Local children:T_irrArray_ISceneNode_Ptr=_node.getChildren()
		Local childcnt:Int=children.Size()
		
		If childcnt>0
			Local tempnode:T_irrISceneNode
			For Local i:Int=0 To childcnt-1
				tempnode=children.elementAt(i)
				If tempnode.getName()=name
					child=tempnode
					Exit
				EndIf		
			Next
		EndIf

		If Not child Then Return Null Else Return findEntity(child)
	EndMethod

	' ----------------------------------------------------------------------
	' not sure about the following
	' ----------------------------------------------------------------------

	' TODO: not sure about global
	Method Position(x:Float,y:Float,z:Float,globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setPosition(T_irrVector3df.createFromVals(x,y,z))
	EndMethod
	
	Method Rotate(pitch:Float,yaw:Float,roll:Float,globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setRotation(T_irrVector3df.createFromVals(pitch,yaw,roll))				
	EndMethod
	
	Method Move(x:Float,y:Float,z:Float)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If x<>y Then x:*Delta.Time()
		If y<>0 Then y:*Delta.Time()
		If z<>0 Then z:*Delta.Time()
		Local dest:T_irrVector3df=T_irrVector3df.createFromVals(x,y,z)
		_node.getRelativeTransformation().transformVect(dest)
		_node.setPosition(dest)
	EndMethod
	
	Method Turn(pitch:Float,yaw:Float,roll:Float,globl:Int=False)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If pitch<>0 Then pitch:*Delta.Time()
		If yaw<>0 Then yaw:*Delta.Time()
		If roll<>0 Then roll:*Delta.Time()
		_node.setRotation(_node.getRotation().Plus(T_irrVector3df.createFromVals(pitch,yaw,roll)))
	EndMethod

	Method Translate(x:Float,y:Float,z:Float)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If x<>0 Then x:*Delta.Time()
		If y<>0 Then y:*Delta.Time()
		If z<>0 Then z:*Delta.Time()
		Local m:T_irrMatrix4=T_irrMatrix4.create()
		m.setTranslation(T_irrVector3df.createFromVals(x,y,z))
		Local pos:T_irrVector3df=_node.getPosition()
		m.translateVect(pos)
		_node.setPosition(pos)		
	EndMethod
	
	' TODO: implement
	Method Point(target:ib3d_Entity)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		PointToVect(target._node.getPosition())
	EndMethod
	
	Method PointToVect:T_irrVector3df(target:T_irrVector3df)
		Rem
		Local diff:T_irrVector3df=_node.getPosition().Minus(target)
		Local dist:Float=Sqr((diff.getX()*diff.getX())+(diff.getZ()*diff.getZ()))
		Local pitch:Float=ATan2(diff.getY(),dist)
		Local yaw:Float=ATan2(diff.getX(),-diff.getZ())		
		Rotate(pitch,yaw,0)
		EndRem
		
		Local pos:T_irrVector3df=_node.getPosition()
		Local xdiff:Float=target.getX()-pos.getX()
		Local ydiff:Float=target.getY()-pos.getY()
		Local zdiff:Float=target.getZ()-pos.getZ()
		Local dist:Float=Sqr((xdiff*xdiff)+(zdiff*zdiff))
		Local pitch:Float=ATan2(ydiff,dist)
		Local yaw:Float=ATan2(xdiff,-zdiff)
		Rotate(pitch,yaw,0)

		
		Rem
		xdiff# = EntityX(entity)-x#
		ydiff# = EntityY(entity)-y#
		zdiff# = EntityZ(entity)-z#
		dist#=Sqr#((xdiff#*xdiff#)+(zdiff#*zdiff#))
		pitch# = ATan2(ydiff#,dist#)
		yaw#   = ATan2(xdiff#,-zdiff#)
		RotateEntity entity,pitch#,yaw#,0
		EndRem		
	EndMethod
	
	' TODO: note index only support 0,1
	' TODO: implement animated texture support
	Method setTexture(texture:TEXTURE,frame:Int=0,index:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setMaterialTexture(index,texture.tex)
	EndMethod
	
	Method setDebugDataVisible(bShow:Int)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.setDebugDataVisible(bShow)
	EndMethod

    	Method SetColor(red:Float,green:Float,blue:Float,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local color:T_irrSColor=T_irrSColor.createFromVals(0,red,green,blue)
		Local colorf:T_irrSColorf=T_irrSColorf.createFromSColor(color)
		
		_node.getMaterial(MaterialIDX).getDiffuseColor().set(colorf.getAlpha(),colorf.getRed(),colorf.getGreen(),colorf.getBlue())
    		_node.getMaterial(MaterialIDX).getAmbientColor().set(colorf.getAlpha(),colorf.getRed(),colorf.getGreen(),colorf.getBlue())
    	EndMethod

	Method setAmbientColor(red:Float,green:Float,blue:Float,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local color:T_irrSColor=T_irrSColor.createFromVals(0,red,green,blue)
		Local colorf:T_irrSColorf=T_irrSColorf.createFromSColor(color)
		
    		_node.getMaterial(MaterialIDX).getAmbientColor().set(0,colorf.getRed(),colorf.getGreen(),colorf.getBlue())
	EndMethod

	Method setDiffuseColor(red:Float,green:Float,blue:Float,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local color:T_irrSColor=T_irrSColor.createFromVals(0,red,green,blue)
		Local colorf:T_irrSColorf=T_irrSColorf.createFromSColor(color)
		
    		_node.getMaterial(MaterialIDX).getDiffuseColor().set(0,colorf.getRed(),colorf.getGreen(),colorf.getBlue())
	EndMethod
	
	Method setEmissiveColor(red:Float,green:Float,blue:Float,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local color:T_irrSColor=T_irrSColor.createFromVals(0,red,green,blue)
		Local colorf:T_irrSColorf=T_irrSColorf.createFromSColor(color)
		
    		_node.getMaterial(MaterialIDX).getEmissiveColor().set(0,colorf.getRed(),colorf.getGreen(),colorf.getBlue())
	EndMethod

	Method setSpecularColor(red:Float,green:Float,blue:Float,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		Local color:T_irrSColor=T_irrSColor.createFromVals(0,red,green,blue)
		Local colorf:T_irrSColorf=T_irrSColorf.createFromSColor(color)
		
    		_node.getMaterial(MaterialIDX).getSpecularColor().set(0,colorf.getRed(),colorf.getGreen(),colorf.getBlue())
	EndMethod														

	Method setFX(E_MATERIAL_FLAG:Int,bNewVal:Int,MaterialIDX:Int=-1)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If MaterialIDX>=0 Then
			_node.setMaterialFlag(E_MATERIAL_FLAG,bNewVal)
		Else
			_node.getMaterial(MaterialIDX).setFlag(E_MATERIAL_FLAG,bNewVal)
		EndIf
	EndMethod

	Method SetBlend(E_MATERIAL_TYPE:Int,MaterialIDX:Int=-1)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If MaterialIDX>=0 Then
			_node.setMaterialType(E_MATERIAL_TYPE)
		Else
			_node.getMaterial(MaterialIDX).setMaterialType(E_MATERIAL_TYPE)
		EndIf
	EndMethod

	Method setShininess(shininess:Float=20.0,MaterialIDX:Int=0)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		_node.getMaterial(MaterialIDX).setShininess(shininess)
	EndMethod
	
	Method getDistanceFrom:Double(entity:ib3d_Entity)
		If Not _node Or Not _node.isValid() Then RuntimeError "Node is invalid"
		If Not entity._node Or Not entity._node.isValid() Then RuntimeError "Distance node is invalid"
		Return _node.getPosition().getDistanceFrom(entity._node.getPosition())
	EndMethod
												
EndType


do you know how the custom importer is suppose to work?


you will need to extend type T_irrIMeshLoader type. override isALoadableFileExtension() and return true if you can load the file passed in. override the createMesh method. this method must return an instance of T_irrIAnimatedMesh. there is no way to actually _create_ T_irrIAnimatedMesh, but that is what T_irrSAnimatedMesh is for. so you essentially return an instance of T_irrSAnimatedMesh. you then create an instance of your new type and then pass it to the AddExternalMeshLoader() method of T_irrISceneManager.

HTH :)