CSP/UCI implementation problem

Blitz3D Forums/Blitz3D Programming/CSP/UCI implementation problem

ZombieWoof(Posted 2004) [#1]
Having a bit of trouble getting a Unique Color Index exterior child detector to work right.

Whats happening is that once I have set all the entity/surface colors, render to buffer and lock, scanning the pixels returns many pixels that have colors that I never set on any mesh.

I'm using a color table to make the mesh easier to read visually, so I know exactly what colors are possible, but ReadPixelFast is returning pixels that are not in my list.

I've even gone so far as setting brushes for each surface, but still get wrong color values.

can someone look over the code and tell me where I blew it ?

2nd problem -- the mmesh I'm testing with is offset, and I havent been able to get it centered back up using meshwidth/height/depth and fitmesh -- any ideas how to fix it up ?? (need something to automatically center up the loaded mesh so I can adjust camera distance so the mesh fills the view) Walk the verts and get the real bounding box then positionmesh ??

http://www.camelot-software.com/files/exterior.zip


Techlord(Posted 2004) [#2]
ZombieWoof,

Checking out your code now. Heres how I'm handling the Color identifier For the sub meshes. You may Or may Not find it useful.

Note: these are excepts from different modules
;color table
Dim VisColorID%(16777216)

;load mesh w/submeshes

;color the submeshes
For loop = 1 To submeshes%
	;check if mesh is virtual or tranparent if so hide and exclude from PVP Check
	If Not excludedmesh%
		;assign color id to mesh
		red%=(loop And $ff0000)Shr 16
		green%=(loop And $ff00)Shr 8
		blue%=(loop And $ff)
		;bind colorid to meshid
		VisColorID%(-(blue% Or (green% Shl 8) Or (red% Shl 16) Or ($ff000000)))=loop% 
		EntityColor submesh%[loop],red%,green%,blue%
		EntityFX submesh%[loop],5;1:full-bright + 4:flatshaded 		
	End If
Next

;capturing the pixels
;move and orientate camera

;create new VIS instance

;render 3d world to backbuffer
RenderWorld()
						
LockBuffer BackBuffer()
	For y=0 To GraphicsHeight() Step detail%
		xoffset=detail%-xoffset%
		For x= xoffset To GraphicsWidth() Step detail%
			;pixel color is equal to submesh color id
			visiblesubmesh%=VISColorID%(-ReadPixelFast(x,y,BackBuffer())) 
			If visiblesubmesh%
				;check the submesh list first to omit further checking if unnecessary
				For loop = 1 To VIS\entities% 
					If visiblesubmesh%=VIS\entityid%[loop]
						visiblesubmesh%=0			
						Exit
					EndIf
				Next
				;if submesh not on list add it
				If visiblesubmesh% 
					VIS\entities%=VIS\entities%+1
					VIS\entityid%[VIS\entities%]=visiblesubmesh%
				EndIf		
			EndIf
		Next
	Next
UnlockBuffer BackBuffer()



ZombieWoof(Posted 2004) [#3]
looks alot like my code :) and the code in csp_vis.zip :)

Thanks for taking a look !!


N(Posted 2004) [#4]
Sorry for going off-topic here, but I had to ask something.

Frank: Are you typing your replies up in the Blitz IDE (or any other IDE with case-correction)? 'Cause I've noticed that words in your post found in the Blitz keywords list have the case that the Blitz IDE would give them... Just a passing thought.


ZombieWoof(Posted 2004) [#5]
@noel: I forgive you :)


Techlord(Posted 2004) [#6]
Noel R. Cower,

Yes, I use the Blitz IDE and that code is directly out of it.


ZombieWoof(Posted 2004) [#7]
@frank: anything pop out at you as a glaring boneheaded mistake in my code yet ?? :)


ZombieWoof(Posted 2004) [#8]
I've been digging more, and I'm really confused.

what could possibly cause a child to render as anything other than the color I tell it to when using fullbright+flatshade ??

the scanned r/g/b values are so far off that I cant reasonably match them to any of the colors which the code supposedly used. I could understand and compensate for the color being off by a 1 or 2 units for each of r/g/b, but this is way beyond that.


jfk EO-11110(Posted 2004) [#9]
make sure you run it in 32 bit or 24 bit resolution, and disable fog. If the meshes have textures, retexture them with a dummy texture that is completely white (explicit 255,255,255). (there might be other ways, but this one works too). Also, Alpha doesn't work, so make sure nothing is alpha-transparent.

Wait, after reading you latest post I think it must be something diffrent. I suspect you are using some crazy materials instead of the good old diffuse texture mapping? Did you model the meshes yourself? And if yes, which tool did you use and what materials?


Techlord(Posted 2004) [#10]
ZombieWoof,

TBH, I would suppect your problem to be in the assignment of colors.
;prepare Children for BSP-precalculation
For x=1 To n_chlds
	kid(x)=GetChild(mesh,x)
	r = ctab_r(x)
	g = ctab_g(x)
	b = ctab_b(x)
	pix = (r Shl 16) + (g Shl 8) + b
	SetColor(kid(x),r,g,b)
	DebugLog "kid="+x+" pix="+pix+" Color="+r+","+g+","+b
	EntityFX kid(x),5
	vis(x) = 0
Next
I'm not sure why your using the 'c_tab' in that fashion. I would simply apply the color directly to the kid(x).
Dim ctab(16777216)

;prepare Children for BSP-precalculation
For x=1 To n_chlds
	kid(x)=GetChild(mesh,x)
	r%=(x And $ff0000)Shr 16
	g%=(x And $ff00)Shr 8
	b%=(x And $ff)
	;bind colorid to meshid
	c_tab(-(b Or (g Shl 8) Or (r Shl 16) Or ($ff000000)))=x ;c_tab color = readpixel equivalent
	EntityColor kid(x),r,g,b
	EntityFX kid(x),5; 1:full-bright + 4:flatshaded
	vis(x)=0 
Next
With following code you can read the backbuffer pixel with:
pix=c_tab(-ReadPixelFast(xx,yy,BackBuffer()))
If pix ;equals kid(x) color id
	;Check VIS List, if kid id on list do nothing
	;if not on VIS List, Add to VIS List
EndIf
Additionally, your VIS does not account for position and scale. This will be necessary later to determine player's is within a specific vis. I manage this by moving the camera's position starting at the maps lowest xyz to its hightest xyz at a specific increment value. I also rotate the cameras at specific angles with each move. Thus, my VIS object looks like this (although I use types, this is an array version)
vis_mapid(n)
vis_x#(n)
vis_y#(n)
vis_z#(n)
vis_scalex(n)
vis_scaley(n)
vis_scalez(n)
vis_kids(n)
vis_kid(n,x)
vis_adjacentvis(n)
vis_adjacent(n,x)
Heres how my camera movement looks for each snapshot
For camposx = mapminx to mapmaxx step 2
	For camposy = mapminy to mapmaxy step 2
		For camposz = mapminz to mapmaxz step 2
			vis=vis+1
			vis_x#(vis)=camposx
			vis_y#(vis)=camposy
			vis_z#(vis)=camposz
			
			For camrotx= 0 to 45 step 15
				For camroty=0 to 270 step 90
					RenderWorld 
					;Readpixels and add kids to vis(vis,kid)
				next
			next
		next
	next
next
Note: I keep a list of adjacent VIS to keep the VIS check very brief. Also, vis objects can be merged for optimization.


ZombieWoof(Posted 2004) [#11]
@frank: this one is specifically to determine what is visible from outside a mesh, not a true CSP. Like terrain that has true CSP done on it, with buildings placed that are VERY high poly -- this code is gonna reduce those buildings to something managable until a player enters a building. I dont want to make the buildings part of the terrain mesh at this point, which would require extending this code to handle multiple child levels, or flattening everything to one child level.

I'm using the ctab because applying the color directly made an image that I was unable to visually interpret, ctab makes sure the colors are visually distinct to help me debug. Without the ctab, I would have never figured that ReadPixelFast was returning colors I had never applied to the mesh.


@jfk: Model was created with Poser and exported as 3DS, none of the textures have been copied to the working folder. Didnt figure I'd need them for this test.

Due to problems with the Poser export, the model is a mix of default materials and textures (thats my next project, to read the poser pz3 scene file and fix the exported model, if I dont just go nutz and write a pz3 loader).

Model is a composite of props from many sources, so I really have no idea what materials and textures are set (I'm a programmer, not a modeler, the 3ds file is in the zip :)

created a 1024x1024 white png file and loaded that as the texture, applied it to the parent and each child, disabled fog -- no change in the behavior of the code.

It's definitly got something to do with specific surfaces, my code randomizes the ctab list every run, colors applied to a given child are rarely the same from run to run, yet the code is very consistent about which surfaces it can see.

I changed the child coloring code to PaintEntity using a brush with color/texture set, no change in behavior.

My desktop is running 32 bit and the app runs in a window, graphics setting is 32 bit. Tried it full screen, no change.

I realized some of the surfaces were not getting the entity color... This is the last thing I've tried before posting:

[code]
Function SetColor(mesh,r,g,b)
EntityColor mesh, r,g,b
EntityFX mesh,5
EntityAlpha mesh,1
EntityShininess mesh,0
EntityTexture mesh, tex
For k=1 To CountSurfaces(mesh)
PaintSurface(GetSurface(mesh,k), GetEntityBrush(mesh))
Next
For k=1 To CountChildren(mesh)
SetColor(GetChild(mesh, k), r,g,b)
Next
End Function
[code]

if I comment out the surface loop, SOME of the children match up colors and are marked visible. if I leave it in, everything gets a unique color, but NONE (and I mean absolutly NONE) of the colors scanned off the rendering match colors in ctab.

modified the code to count the unique colors scanned off the rendering. there are 33 children, 30 unique colors were detected.

So we are back to "why isnt it using the colors I tell it to ?"


jfk EO-11110(Posted 2004) [#12]
btw a white 16*16 pixel would be enough. just checking you model...


ZombieWoof(Posted 2004) [#13]
I actually started with a 32x32, but changed to 1024x1024 in case uv coords needed the bigger tex.. I dont understand texturing that well so decided to play it safe :)

updated the zip file if you want to check the latest code.


jfk EO-11110(Posted 2004) [#14]
ok

When you use LoadAnimMesh then you need to use Countchildren and CountSurfaces NESTED. Since your model has no tree hierarchy (child of child fo child etc.) like in animated Meshes (eg. hand is child of arm, arm is child of shoulder ...), you don't need to parse the children recursively, this makes it easier.

Yes, you had some materialbased colors on the children, that's why you have to set all surfaces of each child:

Graphics3D 640,480,32,2
SetBuffer BackBuffer()

cam=CreateCamera()
TranslateEntity cam,0,0,-10

mesh=LoadAnimMesh("smithy.3ds")

brush=CreateBrush()
BrushColor brush,255,255,255

For i=1 To CountChildren(mesh)
  kid=GetChild(mesh,i)
  EntityFX kid,5
  For i2=1 To CountSurfaces(kid)
   ; example of unique colors:
;   uc=count+1
;   BrushColor brush,uc And $ff0000,uc And $ff00,uc And $ff
   surf=GetSurface(kid,i2)
   PaintSurface surf,brush
   count=count+1
  Next
Next

While Not KeyDown(1)
 TurnEntity mesh,0,1,0
 RenderWorld()
 Flip
Wend
End



The center problem is a bit more tricky. Maybe you better center the mesh in the App you saved it. (usually you only have to adjust the main pivot).


jfk EO-11110(Posted 2004) [#15]
oh yeah, btw, maybe you should use unique colors for each child, not for each surface as in the example above. fo rthis you would position the count=count+1 after the i2-next command. So you can hide and show children dynamicly. And maybe you should also store the chidren handles (kid) in an array...


ZombieWoof(Posted 2004) [#16]
I'm using UCI for each child with a recursive function to set every sub-child and surface to the UCI. I'm not allocating UCIs below the top level children. (a future version might for sub-children, but never individual surfaces. In any case, want to get the basics working)

I pasted in the code for the recursive function a coupla posts ago.

I do store the visible handles in an array, but I was thinking perhaps to save the results as b3d with alpha 0 on all non-visible children. Then the runtime lib can scan for alpha=0 children on load to get the vis-list, and working in blitz based terrain/modeling apps will be easier cause the hidden stuff wont load down the engine during placement. If thats not workable, I'll just save a stripped version of the mesh for placement work.

is there an IRC channel some place where I can talk with you about this real time ?? or can we hook up on instant messaging (I'm on all of them, so it doesnt matter which one)


jfk EO-11110(Posted 2004) [#17]
uh, I rarely chat.

Probably not workable to save invisible parts as alpha zero - you'd have a high number of huge meshes in memory then.

I just saw your children have nice names (entityname$(kid))
Why don't you simply store lists containing names and visibility? This way you can easily load it again and hide everything that was invisible in the UCI test. Well, you model smithy.3ds would work perfect with this method.


ZombieWoof(Posted 2004) [#18]
re: chat: Otay -- had to ask :)

re: meshes in memory -- ya, but I'd only have one model file to cope with during placement and preprocessing -- it doesnt matter, I'll do whatever it takes to create a complete pipeline from terrain+props to configured world and runtime loader.

still dont know what to do about the blown colors. any more ideas on that ??


ZombieWoof(Posted 2004) [#19]
got it -- something you had in that code frag up there, a white brush -- so I created a white brush, painted it on all the surfaces in my recursive loop, THEN set the entity color to the UCI

working perfectly now !!

updated source code at http://www.camelot-software.com/files/exterior.zip

I'll be turning this into a full tool with command line support and an output file with the vis data shortly. gotta add mesh centering and entity naming for un-named child entities.


Techlord(Posted 2004) [#20]
ZombieWoof,

So was the problem in the assignment of colors?


ZombieWoof(Posted 2004) [#21]
the problem was the brush on each surface, and my misunderstanding, thinking the brush was the color -- its not. its the texture/material that the entity color will be applied to.

If I had not used entity colors, just surface brushes, might have worked that way too. but using both caused the colors to change.


jfk EO-11110(Posted 2004) [#22]
BTW the Term UCI was reversed to ICU, because its cooler :)
(Identification of Colors by Uniqueness)


ZombieWoof(Posted 2004) [#23]
My girlfiend used to be an RN, so I chose not to use ICU to avoid confusion when discussing issues with her (she is one of my artists)

got the centering code working to get the model to 0,0,0 so the rotation is correct (model is not moving left to right or forward/back)

now gotta add command line handling, gui, and the output file.


Techlord(Posted 2004) [#24]
ZombieWoof,

You can always spell it out like : I See You. Which is totally acceptable for the process:) I See You... Polygons.


ZombieWoof(Posted 2004) [#25]
hehehe now that sounds like my instant messenger :)

lemme get back to work -- once I got the command line and gui done, I got some C#.Net work to do setting up a project manager/builder for maps/worlds -- you know -- automate the process of converting/preparing/etc artwork for use in a game :)

Functionality like the Make command or the VS.Net IDE -- point it at your models, set properties to control what conversions/preprocessing are to be done on the model, and when a model is updated, only the processing neccessary to bring the project up to date gets executed.

Plugins so you can add new properties/processes to a model type, so the build system can be extended as new technologies become available.

gonna be fun to code up :)


ZombieWoof(Posted 2004) [#26]
some days it just doesnt pay -- went and grabbed a copy of Protean IDE, and started breaking up the code into modules..... of course I broke the code in the process, and cant figure where I blew it :)

Someplace between loading the mesh and rendering, the mesh goes bye-bye -- getting a lotta nothin -- no tris rendered