Collisions (bah!)

Blitz3D Forums/Blitz3D Programming/Collisions (bah!)

Im having real difficulty trying to get EntityBox to be of any use. Whatever values I use, don't seem to represent the effeccts I see in the program.

Here's what I have anyway (I removed references to Loading texture files so it should just run as-is.)

Hopefully it should be clear enough whats going on, the EntityBox lines are withing the CreateWall function and at the Initialisation stage where the camera is set.

Any help offered here will be immensely appreciated!

;Dungeon 

 
Graphics3D 800,600,32,2

SetBuffer BackBuffer()


;*****************************INITIALISE******************************

SeedRnd MilliSecs()

AmbientLight 160,160,160

Global cam=CreateCamera()

EntityType cam,2,0
EntityBox cam,0,0.5,0,0.5,1,0.5


CameraViewport cam,0,0,800,600
CameraRange cam,0.01,10

ScaleEntity cam,0.5,1,0.5

CameraFogMode cam,1
CameraFogColor cam,1,1,1
CameraFogRange cam,-12,8

camlight=CreateLight(2)
EntityParent camlight,cam,1

LightRange camlight,1


Global fpcounter#
Global timer

Global poison=0
Global tempPoison#=0
Global tpadd#=0.01
;****************************BUILD ARRAYS *****************************

Dim vpos#(1,1)
Dim Map(200)

;***************************CREATE QUICK RANDOM MAP**********************


Fl=CreatePlane()
MoveEntity fl,0,-1,0


	For f= 1 To 200

		Map(f)=CreateWall()
			
		ScaleMesh Map(f),1,2,1
		
			If f>1
				AddMesh Map(f),Map(f-1)
			EndIf
		
		
		Morph(Map(f))
						
		PositionEntity Map(f),Rand(-15,15),0,Rand(-15,15)
		
	Next
	
	
;******************************* SET COLLISIONS ******************

Collisions 3,2,3,1
Collisions 2,3,3,1

;*************************** MAIN LOOP ****************************

Global fps#=0

timer=MilliSecs()

While Not KeyDown(1)

PositionEntity cam,Int(EntityX(cam)),0,Int(EntityZ(cam))
RotateEntity cam,0,Int(EntityYaw(cam)),0

;*************************CONTROLS*****************************




If KeyDown(200) Then walkforward(cam)
If KeyDown(208) Then walkbackward(cam)

If KeyDown(203) Then turnleft(cam)
If KeyDown(205) Then turnright(cam)

If KeyDown(25)

			Delay 150
			
			poison = (1-poison)
			
			If poison=1 Then AmbientLight 160,220,160
			
			If poison=0 
				CameraZoom cam,1
				AmbientLight 160,160,160
				tempPoison=0
			EndIf
EndIf
			

;*************************TORCHLIGHT*******************************
If poison=0 Then LightColor camlight,Rand(fpcounter*5),Rand(170,220),100
If poison=1 Then LightColor camlight,0,50,0
		render()











Wend
End

;*******************************************FUNCTIONS************************




Function walkforward(entity)

	If poison=1	Then CameraClsMode cam,0,0

For f= 1 To 5 

MoveEntity entity,0,0.02,0.1

	

render()

Next

For f= 1 To 5 

MoveEntity entity,0,-0.02,0.1

	

render()

Next

	If poison=1	Then CameraClsMode cam,1,1

End Function




Function walkbackward(entity)

	If poison=1	Then CameraClsMode cam,0,0

For f= 1 To 5 

MoveEntity entity,0,0.02,-0.1

	

render()

Next

For f= 1 To 5 

MoveEntity entity,0,-0.02,-0.1

	

render()

Next

	If poison=1	Then CameraClsMode cam,1,1

End Function


Function turnleft(entity)

For f=1 To 20

TurnEntity entity,0,4.5,0

	
render()

Next

End Function


Function turnright(entity)

For f=1 To 20

TurnEntity entity,0,-4.5,0

render()

Next

End Function







Function CreateWall()

;*****************************CREATE SEGMENTED CUBE FROM 6 SIDES **************

	mesh=CreateMesh()
	
	segs=3
	
	For scnt=0 To 3
		surf=CreateSurface( mesh )
		stx#=-.5
		sty#=stx
		stp#=Float(1)/Float(segs)
		y#=sty
		For a=0 To segs
			x#=stx
			v#=a/Float(segs)
			For b=0 To segs
				u#=b/Float(segs)
				AddVertex(surf,x,y,0.5,u,v)
				x=x+stp
			Next
			y=y+stp
		Next
		For a=0 To segs-1
			For b=0 To segs-1
				v0=a*(segs+1)+b:v1=v0+1
				v2=(a+1)*(segs+1)+b+1:v3=v2-1
				AddTriangle( surf,v0,v1,v2 )
				AddTriangle( surf,v0,v2,v3 )
			Next
		Next
		RotateMesh mesh,0,90,0
	Next

	UpdateNormals mesh
	
	EntityType Mesh,3,1
	
	EntityBox mesh,0,0,0,0.3,2,0.3

Return mesh
End Function


;**************************MORPH VERTS*****************************

Function Morph(mesh)

surftotal=CountSurfaces(mesh)

For xx= 1 To surftotal
as1=GetSurface(mesh,xx)

; record the locations of the verts
Dim vpos#(CountVertices(as1)-1,3)
For n=0 To CountVertices(as1)-1
	vpos(n,0)=VertexX(as1,n)
	vpos(n,1)=VertexY(as1,n)
	vpos(n,2)=VertexZ(as1,n)
	vpos(n,3)=0
Next

For n=0 To CountVertices(as1)-1

; change these to make it more or less messy
xm#=Rnd(-.2,.2)
ym#=Rnd(-.0,.0)
zm#=Rnd(-.2,.2)

	For nn=0 To CountVertices(as1)-1
	
	; if the vert has not been monkeyed with monkey away
	If vpos(nn,3)=0
		If vpos(n,0)=vpos(nn,0) And vpos(n,1)=vpos(nn,1) And vpos(n,2)=vpos(nn,2)
			VertexCoords as1,nn,vpos(nn,0)+xm,vpos(nn,1)+ym,vpos(nn,2)+zm
			vpos(nn,3)=1
			EndIf
		EndIf
		
	Next
Next

Next

Return mesh

End Function


Function render()

;*************************MAINTAIN FACING*******************

RotateEntity cam,0,EntityYaw(cam),0

	If poison=1

		tempPoison#=tempPoison#+tpadd#
		If TempPoison#>1 Then tpadd#=(0-0.01)
		If TempPoison#<0.8 Then tpadd#=0.01
			CameraZoom cam,tempPoison#
	EndIf

UpdateWorld
RenderWorld

Text 0,100,"POLYS: "+TrisRendered(),0,1

Text 0,200,"FPS: "+fps#,0,1

If poison=1 Text 0,250,"POISON AFFLICTION APPLIED",0,1

fpcounter#=fpcounter#+1

	If (MilliSecs()-timer)>=1000
		timer=MilliSecs()
		fps#=fpcounter#
		fpcounter#=0
	EndIf

Flip

End Function


; COLLISIONS INDECES

;1 = PLAYER
;2 = CAMERA
;3 = WALL


Note that the EntityBox command should be used in a similar way to FitMesh ... so for a centered cube of length 1 unit size if would be EntityBox, entity,-.5,-.5,-.5,1,1,1.

I haven't really looked at your code so I'm not sure if that helps. Also, I don't think that the entitybox aligns with the entity during rotations ... could be wrong though as I never use them.

Stevie

Well although all the wall meshes are slightly deformed, tey still fit roughly to blitz-unit coords. This is all I need for collisions, just the blitz units, Each wall segment has an approximate square base, and are not rotatetd anyway, so rotations shouldnt matter.

I gathered that EntityBox sizes should represent blitz units as the coords, but in practice it doesnt seem so - thats my problem. I wonder if the EntityBox coordinates relate to the centre of me wall segemnts.. this might have something to do with it...

Of course EntityBox uses blitz units - what else would it use? :)

To elaborate on what Stevie G showed you, the first 3 params of EntityBox are used to say where a corner (any corner) of the box is, relative to the centre of the mesh. The final 3 params specify where the opposite corner of the box is, relative to the first corner.

Well, that's how I remember it working, anyway - it's been a while. The docs for EntityBox are sparse and somewhat misleading, it has to be said.

This bit of code is a bit strange and makes very little sense to me as you arent freeing the added mesh. If your going to add all the meshes together then you must use the sphere to poly collision as sphere to box will definately not work. You have unused meshes all over the place?!


If f>1
				AddMesh Map(f),Map(f-1)
			EndIf




Anyway, I fiddled about with this for a bit but got nowhere as the code is a wee bit messy ;) I changed and simplified a few things and this works. Hope it helps.



;Dungeon 

Graphics3D 800,600,32,2

; COLLISIONS INDECES
Const C_PLAYER = 1
Const C_WALL = 3
Const C_CAMERA = 2

SetBuffer BackBuffer()


;*****************************INITIALISE******************************

SeedRnd MilliSecs()

AmbientLight 160,160,160

Global cam=CreateCamera()
EntityType cam,C_CAMERA
EntityRadius cam,.5

CameraViewport cam,0,0,800,600
CameraRange cam,0.01,10
CameraFogMode cam,1
CameraFogColor cam,1,1,1
CameraFogRange cam,-12,8

camlight=CreateLight(2)
EntityParent camlight,cam,1

LightRange camlight,1


Global fpcounter#
Global timer

Global poison=0
Global tempPoison#=0
Global tpadd#=0.01
;****************************BUILD ARRAYS *****************************

Dim vpos#(1,1)
Dim Map(200)

;***************************CREATE QUICK RANDOM MAP**********************

Fl=CreatePlane()
MoveEntity fl,0,-1,0

For f= 1 To 200
	Map(f) = CreateCube()
	ScaleEntity Map(f), 1, 2, 1
	EntityBox Map(f), -1,0,-1,2,4,2
	EntityType Map(f), C_Wall
	;Map(f)=CreateWall()
	;Morph( Map(f) )
	PositionEntity Map(f),Rand(-15,15)*2,0,Rand(-15,15)*2
Next
	
;******************************* SET COLLISIONS ******************

Collisions C_CAMERA, C_WALL,3,1

;*************************** MAIN LOOP ****************************

Global fps#=0

timer=MilliSecs()
ActionTimer = 0

While Not KeyDown(1)

;PositionEntity cam,Int(EntityX(cam)),0,Int(EntityZ(cam))
;RotateEntity cam,0,Int(EntityYaw(cam)),0

;*************************CONTROLS*****************************

If ActionTimer = 0
	Move# = KeyDown(200) - KeyDown(208 ) 
	Turn# = KeyDown(203) - KeyDown(205 ) 
	If Move <> 0 ActionTimer = 10
	If Turn <> 0 ActionTimer = 20 : Move = 0
Else
	If Move <> 0 
		MoveEntity Cam,0,0, Move * .2
	Else
		TurnEntity Cam , 0, Turn * 4.5 , 0
	EndIf
	ActionTimer = ActionTimer - 1
EndIf

If poison=1 Then CameraClsMode cam,0,0

If KeyDown(25)
	Delay 150
	poison = (1-poison)
	If poison=1 Then AmbientLight 160,220,160
	If poison=0 
		CameraZoom cam,1
		AmbientLight 160,160,160
		tempPoison=0
	EndIf
EndIf
			

;*************************TORCHLIGHT*******************************
If poison=0 Then LightColor camlight,Rand(fpcounter*5),Rand(170,220),100
If poison=1 Then LightColor camlight,0,50,0
		render()


Wend
End

;*******************************************FUNCTIONS************************

Function CreateWall()

;*****************************CREATE SEGMENTED CUBE FROM 6 SIDES **************

	mesh=CreateMesh()
	
	segs=3
	
	For scnt=0 To 3
		surf=CreateSurface( mesh )
		stx#=-.5
		sty#=stx
		stp#=Float(1)/Float(segs)
		y#=sty
		For a=0 To segs
			x#=stx
			v#=a/Float(segs)
			For b=0 To segs
				u#=b/Float(segs)
				AddVertex(surf,x,y,0.5,u,v)
				x=x+stp
			Next
			y=y+stp
		Next
		For a=0 To segs-1
			For b=0 To segs-1
				v0=a*(segs+1)+b:v1=v0+1
				v2=(a+1)*(segs+1)+b+1:v3=v2-1
				AddTriangle( surf,v0,v1,v2 )
				AddTriangle( surf,v0,v2,v3 )
			Next
		Next
		RotateMesh mesh,0,90,0
	Next

	UpdateNormals mesh
	
	EntityType Mesh,C_WALL
	
	EntityBox mesh,-.15,0,-.15,1.5,2,1.5 

Return mesh
End Function


;**************************MORPH VERTS*****************************

Function Morph(mesh)

surftotal=CountSurfaces(mesh)

For xx= 1 To surftotal
as1=GetSurface(mesh,xx)

; record the locations of the verts
Dim vpos#(CountVertices(as1)-1,3)
For n=0 To CountVertices(as1)-1
	vpos(n,0)=VertexX(as1,n)
	vpos(n,1)=VertexY(as1,n)
	vpos(n,2)=VertexZ(as1,n)
	vpos(n,3)=0
Next

For n=0 To CountVertices(as1)-1

; change these to make it more or less messy
xm#=Rnd(-.2,.2)
ym#=Rnd(-.0,.0)
zm#=Rnd(-.2,.2)

	For nn=0 To CountVertices(as1)-1
	
	; if the vert has not been monkeyed with monkey away
	If vpos(nn,3)=0
		If vpos(n,0)=vpos(nn,0) And vpos(n,1)=vpos(nn,1) And vpos(n,2)=vpos(nn,2)
			VertexCoords as1,nn,vpos(nn,0)+xm,vpos(nn,1)+ym,vpos(nn,2)+zm
			vpos(nn,3)=1
			EndIf
		EndIf
		
	Next
Next

Next

Return mesh

End Function


Function render()

;*************************MAINTAIN FACING*******************

RotateEntity cam,0,EntityYaw(cam),0

	If poison=1

		tempPoison#=tempPoison#+tpadd#
		If TempPoison#>1 Then tpadd#=(0-0.01)
		If TempPoison#<0.8 Then tpadd#=0.01
			CameraZoom cam,tempPoison#
	EndIf

UpdateWorld
RenderWorld

Text 0,100,"POLYS: "+TrisRendered(),0,1

Text 0,200,"FPS: "+fps#,0,1

If poison=1 Text 0,250,"POISON AFFLICTION APPLIED",0,1

fpcounter#=fpcounter#+1

	If (MilliSecs()-timer)>=1000
		timer=MilliSecs()
		fps#=fpcounter#
		fpcounter#=0
	EndIf

Flip

End Function



[codebox]

Oops ...

Hey thanks Stevie, yeah it is messy, because it started out just as quick little something whic developed quite well.. I hope to incorporate it as a game engine soon -

Well I had to re-do my head-bobbing code (hence the funcs for walking) and add in again the morphing of the walls (whicch I know caused a lot of collision headaches with irregular verts and camera bbbing), but thanks because of using the entityradius and different collision methods really made a difference.

Ive got it running now with the colisions working fine thanks again.

Thanks again!

hehe, one thing:


wonder if the EntityBox coordinates relate to the centre of me wall segemnts.. this might have something to do with it...



They do.

Glad its fixed :)

thanks Cygnus! That makes a lot of sense now ;)

No prob. ANother note is that they DO rotate with the mesh.

Spherical/eliptical collisions don't.

Your welcome mate. Good luck with your Dungeon Master clone?!

Yes it is! A kinda Dungeon Master/Bloodwych type game (to be!) Hopefully with a few little extra's thrown in!

Cheers!