`jGfx Plugin: GInst Example - Group BVH
`=============================================
`Demonstrates the usage of GInstGroups to build a bounding volume hierarchy around a set of GInstBuffers.
`The library will use the group hierarchy when culling to increase culling efficency in GInstBuffer heavy scenes.
`Because geometry instancing is much heavier on the gpu than cpu, the benefits of BVH culling become most evident
`when all instances are off screen. This example is purposefully heavy on GInstBuffer usage to emphasize culling overhead.
Sw = Desktop Width()
Sh = Desktop Height()
Set Display Mode Sw,Sh,32,1
Sync On : Sync Rate 0
Autocam Off : Color Backdrop 0
Set Camera Range 10, 10000

`Example Settings
bBuildBVH = 1	`Use GInstGroups to build a bounding volume hierarchy for culling.


`Setup Instance Source Object
ObjectID = 1
Make Object Cube ObjectID, 50
Convert Object FVF 1,0x002 || 0x010 || 0x100
Load Image "Media\bricks.png",1
Texture Object ObjectID, 0, 1 `note: set render mesh textures before applying to GInst

`load GInst compatible diffuse effect
Load Effect "Media\GInst_Diffuse.fx",1,0


`Setup a GInst to use as a source for instance data
pGInst = GInst_MakeNew()
`Setup Meshlist
GInst_SetObject pGInst, ObjectID
`Apply effect
GInst_SetEffect pGInst, 1



If bBuildBVH
	`Create a group to represent the BVH Tree's Root Node.
	pRootGroup = GInstGroup_MakeNew()
Endif


`Create 121 groups (11x11) within the root group
BufferWidth = 100.0		`Horizontal size of each GInstBuffer
InstanceCount = 1		`Only one instance per buffer

For GroupX=-5 to 5
	GroupPosX = (BufferWidth*3) * GroupX
	For GroupZ=-5 to 5
		GroupPosZ = (BufferWidth*3) * GroupZ

		If bBuildBVH
			`Create a new group as a child of the root group
			pChildGroup = GInstGroup_MakeNew( pRootGroup )
		endif

		`Create 27 InstBuffers (3x3x3) within the child group
		`3267 InstBuffers will be created in total
		For BufferX=-1 to 1
			BufferPosX = ( BufferX * BufferWidth ) + GroupPosX
			For BufferZ=-1 to 1
				BufferPosZ = ( BufferZ * BufferWidth ) + GroupPosZ
				for BufferY=-1 to 1
					BufferPosY=BufferY*100

					`Make a new instance buffer and fill it with 
					pInstBuffer = GInstBuffer_MakeNew( pGInst, InstanceCount )
					
					
					For i=1 to InstanceCount
						`Set random transforms
						PosX# = ( Rnd(BufferWidth) - (BufferWidth*0.5) ) + BufferPosX
						PosZ# = ( Rnd(BufferWidth) - (BufferWidth*0.5) ) + BufferPosZ
						GInstBuffer_SetPosition pInstBuffer, i, PosX#, BufferPosY, PosZ#
						GInstBuffer_SetRotation pInstBuffer, i, Rnd(360), Rnd(360), Rnd(360)
						GInstBuffer_SetScale pInstBuffer, i, 100.0, 100.0, 100.0
						
						`Update the instance's world matrix
						GInstBuffer_UpdateInstance pInstBuffer, i
					Next i
					
					`Update the InstBuffer to contain the latest instance data
					GInstBuffer_Update pInstBuffer, 1
					
					If bBuildBVH
						`Add the InstBuffer to the child group. This allow the plugin to cull the buffer using the group hierarchy
						GInstBuffer_SetGroup pInstBuffer, pChildGroup
					endif
				
				Next BufferY
			Next BufferZ
		Next BufferX

	Next GroupZ
Next GroupX


Position Camera (-BufferWidth*20), 350, (-BufferWidth*20)
Rotate Camera 25, 45, 0


TimeSpeed# = 0.5
LastTime = Timer()
Do
	Set Cursor 0,0
	Print "FPS = ",Screen Fps()
	Print "Use the mouse and arrowkeys to control the camera"

	Now=Timer()
	TimePassed# = (Now - LastTime)*TimeSpeed#
	LastTime = Now

	Move Camera (UpKey()-DownKey())*TimePassed#
	Move Camera Right (RightKey()-LeftKey())*TimePassed#
	Rotate Camera Wrapvalue(Camera Angle X()+MouseMoveY()),  Wrapvalue(Camera Angle Y()+MouseMoveX()), 0

	Sync
Loop

