Polys from a bitmap
Blitz3D Forums/Blitz3D Programming/Polys from a bitmap
| ||
I want to set up a map that displays a series of coloured areas overlaying a landscape. Ideally the coloured areas would be polys rather than an overlying bitmap so that everything's sharp and I can manipulate individual areas without too much trouble. I could create the polys in a modelling package but I'm fairly sure I'm going to be doing a lot of tweaking before the map's in a final form and a quicker way might be to have a bitmap containing the coloured areas and then the game code generates polys from the (unique) areas of colour. Thing is, has anyone come across code to identify areas of colour within a bitmap and generate polys for them? |
| ||
I didnt test this, but it *should work, the getcolor can be changed to readpixelfast after you lock the buffer This is an adaptation of a floor/terrain loader, so the resulting mesh is parellell to the ground. easily remedied if you need it facing cam just tilt the pitch 90 degrees. basically you toss an image , color and color tolerance, and it makes quads for you only on the pixels that have the proper color, and spits out a flat mesh. This will create pretty high polycount meshes on large images though. You would then need to modify the routine to find rectangles of similar color and make larger scaled quads to cover the region. as it is its one quad per pixel, similar to many heightmap loaders only it can weed out unwanted regions based on colors. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; F U N C T I O N ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function CreateLayer(image,r=255,g=255,b=255,tol=1,scale#=2.0) SetBuffer ImageBuffer(image) Local x# Local y# Local z# segsx=ImageWidth(image) segsy=ImageHeight(image) mesh=CreateMesh() surf=CreateSurface(mesh) For I=1 To segsx For II=1 To segsy GetColor(i,ii) If ColorRed() < r + tol And ColorRed() >r - tol Then If ColorGreen() < g + tol And ColorGreen() >g - tol Then If ColorBlue() < b + tol And ColorBlue() >b - tol Then addquad(mesh,surf,i,ii,1) EndIf EndIf EndIf Next Next UpdateNormals mesh ScaleMesh mesh,scale*2,scale*2,scale*2 UpdateNormals mesh PositionEntity mesh,0,.25,0 setbuffer backbuffer() Return mesh End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; F U N C T I O N ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function addquad(mesh,surf,qx,qy,segs=1) Local ccc=0 Local a=AddVertex(surf,qx ,0,qy ,1 ,0) ; swap these for a different start orientation Local b=AddVertex(surf,qx+segs,0,qy ,1 ,1) ; swap these for a different start orientation Local c=AddVertex(surf,qx+segs,0,qy+segs,0 ,1) ; swap these for a different start orientation Local d=AddVertex(surf,qx ,0,qy+segs,0 ,0) ; swap these for a different start orientation AddTriangle( surf,c,b,a) AddTriangle( surf,d,c,a) End Function |
| ||
RR Thanks for that idea - leads me onto another idea. 1, Make a list of edge pixels. 2, test each pixel as a start pixel and each pixel as an end pixel. 3, test each pixel to see if it would be on the line between start/end pixels. If so, remove from the list. 4, Rinse/repeat until all pixels have been tested. 5, sort remaining pixels by y and then x 6, create polys |
| ||
Is that called 'vectorizing'? It could be complex. http://www.google.com/search?q=vectorization+algorithms&rls=p,com.microsoft:en-gb Or search for "bitmap to polygon". Actually, in the searches, I found this article: http://cardhouse.com/computer/vector.htm Maybe it helps, it contains source code. |
| ||
warner, i take it ur home from vacation? |
| ||
Sure, back again. It was dreadfull living in a tent without a computer. Allthough .. does a PDA count as a computer? :) |
| ||
Is that called 'vectorizing'? It could be complex. Yeah - I've got it working roughly but it falls over when a corner angle is obtuse. I could spend too much time on this - probably better just to allow for area drawing/defining in the game editor. |
| ||
warner, check ur mail |
| ||
Actually, cause I know people will be desperately interested in this, I've created a strategic map mesh in a modeling package and given each area one of twenty different surfaces. The blitz code loads this mesh and checks the vertices for each surface. If the vertex being checked is distant from the previous, then it must be a new area (can't have two areas adjacent using the same surface). The corners for this area are then stored under a new index number. A final check finds areas that are adjacent to the current area are stored as well. Means I can adjust vertex positions in my modelling package and have the data reprocess in blitz. |