Solid CSG Lib for Bmax

BlitzMax Forums/BlitzMax Programming/Solid CSG Lib for Bmax

Leon Drake(Posted 2007) [#1]
Creating a Solid CSG library for Bmax, it is not dependant on any 3d library. uses 3d maths only to calculate CSG operations. However in order to use it you will need to Transfer the Mesh data to the Solid and then back again.

i posted a worklog on it

http://www.blitzbasic.com/logs/userlog.php?log=1525&user=9295

I'll try and add some example files with the mod for B3dSDK and Minib3d


N(Posted 2007) [#2]
That's nice and all, but I don't think you need a thread for this. Especially considering you have nothing to show.


Will(Posted 2007) [#3]
Lol Noel - always nice and all, but I don't think you need a post to say that, especially considering you have nothing to say ;)

Leon - I think it'll be sweet when you've created this, It'd be awesome to use it to do red-faction style geomod!

Would you write in-out methods for use with MiniB3D? That'd really help it to be very useful.


Chroma(Posted 2007) [#4]
Glad to hear it Leon. A lot of people could use some drop-in CSG code for their editors (me).

Noel, any particular reason you're taking a personal attack on this guy? You're lucky I'm not a mod here or I'd just take out the trash for good.


JoshK(Posted 2007) [#5]
Noel, any particular reason you're taking a personal attack on this guy?

Probably because there's a 90% chance this will never materialize.


Gabriel(Posted 2007) [#6]
Noel, any particular reason you're taking a personal attack on this guy? You're lucky I'm not a mod here or I'd just take out the trash for good.

Telling someone they have nothing to show is a statement of fact. It may be blunt, but it's no personal attack. For reference, a personal attack is when you do something daft like call people names. I don't know, like refer to someone as trash, for example.


Chroma(Posted 2007) [#7]
Probably because there's a 90% chance this will never materialize.

That may be, but a response like Noel's gives the impression that no new ideas are wanted or accepted by this community.

Gabriel, and referring to someone as daft too I assume. ;)

Anyways, enough derailing. I think it's a good idea.


Gabriel(Posted 2007) [#8]
That may be, but a response like Noel's gives the impression that no new ideas are wanted or accepted by this community.

That's not the impression I get at all. I get the impression that starting two threads and a worklog on the subject when there's nothing to discuss is overkill.

Gabriel, and referring to someone as daft too I assume. ;)

Sorry, I'm a bit forgetful and I forget which members speak English as a first language and which don't. If you read carefully, you'll see I described an act as daft, not a person. If you're suggesting that only daft people can commit daft acts, I don't actually agree, but I guess I'll take your word for it.


Chroma(Posted 2007) [#9]
Same thing. But do us both a favor, and the community, and just drop it. Thanks.


Leon Drake(Posted 2007) [#10]
well at anyrate i should have something to show tonight. Kind of hard to show any visual progress when im halfway into the library.

I made it so when you request faces from the solid you can set a bool so it will return either Union or Intersection. (i may add Difference, i personally never use it though), but it will return a list of the faces that are visible depending on the bool. no math needed to perform this operation its all about occlusion. all the math is done when you run addsolid method.

I'll see if i can get a screeny up tonight.

Oh BTW thanks Leadwerks, without that pdf you wrote on CSG i might still be scratching my head. The math you show was alot easier to follow than other sources i've looked at.


Leon Drake(Posted 2007) [#11]
BTW i'll include read in-out functions for minib3d and B3dsdk when im finished.

I'm pretty much done now all i gotta do is write the functions for returning the faces of changed solids and a rebuild world method.

and of course test it, so i can fine tune it.


FlameDuck(Posted 2007) [#12]
Same thing. But do us both a favor, and the community, and just drop it.
It's not the same thing, and you were the one who brought it up.

Leon - I think it'll be sweet when you've created this,
Indeed.


Leon Drake(Posted 2007) [#13]
if i work fast enough i should be able to have this done tonight..... well a beta of it anyways.


Leon Drake(Posted 2007) [#14]
BTW noel-

Possibly, i didn't presume i was wasting a thread because im sure i can create this, currently im almost done with it as it is. I suppose i could have waited and just went BAM here it is!

either way this won't be a wasted thread once i publish it. ;)


Sledge(Posted 2007) [#15]
[EDIT: Ah, you changed the sig already!] Looking forward to seeing the lib -- could be the foundation for Neo Maplet, eh?


Leon Drake(Posted 2007) [#16]
lol, you noticed that too? heh heh im gonna change it to something smaller.


Chroma(Posted 2007) [#17]
It is identical. And aside from who brought what up and who chimed in of their own accord...just drop it.

Looking forward to seeing some examples Leon.


Sledge(Posted 2007) [#18]
gonna change it to something smaller

That would be appreciated, the FAQ asks that sig images be no bigger than 80 pixels high in case you haven't seen it (it's quite well hidden).


Leon Drake(Posted 2007) [#19]
ah well this new one's a lil bigger than 80 but eh not too bad now.


N(Posted 2007) [#20]
Noel, any particular reason you're taking a personal attack on this guy? You're lucky I'm not a mod here or I'd just take out the trash for good.
What is it with you people and assuming I'm personally attacking someone? Yeesh, all I did was point out that a thread wasn't needed for a project that already has a worklog and nothing else to show.

Leon, good luck with it, but again, don't need a thread this early.

There, everyone happy that I included 'good luck' and the usual sugar-coating? Now go back to your holes and look for insults elsewhere.


Leon Drake(Posted 2007) [#21]
ROFLMAO


BlitzSupport(Posted 2007) [#22]
Please stop the posts unrelated to the topic.

Leon: looking forward to seeing this!


Leon Drake(Posted 2007) [#23]
bah, im tired. ugh. i need to figure out how to locate the UV of a new point within a face.


Will(Posted 2007) [#24]
If you get time, please add subtraction - I really want to do red-faction style geo-mod.


FlameDuck(Posted 2007) [#25]
i need to figure out how to locate the UV of a new point within a face.
Interpolation?


Leon Drake(Posted 2007) [#26]
like mapping axes. im not sure how to do those.

i saw a bit of math on how to retrieve the UV from a set up mapping axes but i dunno how to set one up for a face.


Leon Drake(Posted 2007) [#27]
ok im sure you guys will find this humorous, after finally fixing some recursive issues i finally got it to a point where i can visually see whats going on. hahaha i got this result.



seems like

a.) I gotta fix the math coordinates when im splitting a face.

b.) its not returning unmodified faces

c.) It's returning the wrong boolean

however i dont plan on giving up. i can finally see whats going on now.


_33(Posted 2007) [#28]
I would really like to see this working, but that image is not convincing at all.


JoshK(Posted 2007) [#29]
It's hard stuff!
http://www.leadwerks.com/post/csg.zip

I have found that splitting the brush edges gives more reliable results than reconstructing a new solid out of planes.


_33(Posted 2007) [#30]
A fully working clipping plane and closed mesh is something I'd need. Big10p did one of those around 2004, it's in the code archive. The only problem with it is that it doesn't close the mesh.

But to me CSG is, for example: Take a rectangle, subtract a smaller rectangle from it (make a tub), then add a sphere on one of the edges and... son on and so forth.


Leon Drake(Posted 2007) [#31]
yea im currently working on splitting edges, i agree it is more reliable. i fixed some probs with that last screenshot. however when i run a ray/edge vs triangle test for some reason the dotproduct is off somewhat. currently im trying to get all the intersection points of the edges to line up correctly. once i get that point working right, splitting edges is pretty much covered.


Leon Drake(Posted 2007) [#32]
that was a pretty neat lil program. was that using occlusion rendering or was that straight up manipulating the geometry?


Leon Drake(Posted 2007) [#33]
Ok i see whats going on

when i test a line to a face, it gives me the XYZ coords but its in integer format so its not exact



and when i try this on testing edges of one mesh to another i get this



i found some source code on getting the distance between the point and the line.

im just having trouble getting
(xyz) - distance#

any ideas?


Leon Drake(Posted 2007) [#34]
ah man got it a pinch closer. but the math is still off a pinch. ergh...




Leon Drake(Posted 2007) [#35]
Ah hah



figured it out.

now to apply this to the solidcsg lib im working on.


Leon Drake(Posted 2007) [#36]
erm maybe not. doesnt seem to work well at some odd angles.


_33(Posted 2007) [#37]
Good luck! Hope it ends up speedy :P


Leon Drake(Posted 2007) [#38]
gotten alot closer. i got all the correct intersection points but they are off. i need to use or write a different line pick code thats more accurate. these ones i got from the code archive do return the intersection point. but its on the triangle and its not completely accurate down to the smallest point. I need one that gives me the intersection point on the line not on the face.

the rest however is covered i can do face splitting and stuff right. but its just getting the correct intersection points that are giving me grief.


Leon Drake(Posted 2007) [#39]
well until i figure out this ray triangle intersection bit i found something cool on the side

there is
http://activesolid.ncf.ca/asdstd.html
an active solid library which can be integrated into Bmax the standard edition has a free license.

the SDK info is a bit vague. it says i can be wrapped in an application that uses a COM container, but thats if you want the full gui etc etc out of it. it contains activesolid.dll which does all the grunt work for solid modelling plus there is an import/export feature so you could transfer a model to the dll have it chop it up and send it back.


Leon Drake(Posted 2007) [#40]
oooh even better one

http://www.geometros.com/sgcore/review.htm#5


Leon Drake(Posted 2007) [#41]
WOOT! progress, got those damn intersection points to line up exactly.



now i can finally start splitting edges, etc etc


_33(Posted 2007) [#42]
sgCore :o

Genius piece of work! I really like the boolean operations and how fast everything gets done. Great :P

I'm thinking, couldn't it be more time saving to adapt sgCore to BlitzMax than rewriting the whole system from scratch? That would be pretty sweet!


Leon Drake(Posted 2007) [#43]
i know , however IR stoopid when it comes to making wrappers for that kind of thing. i would much rather use sgcore.

but at the same time i want the experience learning how to do CSG, i been eyeballing it since UT GOTY and have mildly obsessed with learning it. i remember back when Cshop was my fav tool, but i wanted that power integrated into my own editor because the game i plan on releasing requires user made stuff.

on the flip side, however i got those intersection points much more exact. except now i got a few staggler points that seem to pass the ray intersection test but arent actually intersecting anything see




also here is the code i used to sorta snap to a line,

Function Magnitude#( px#,py#,pz#,dx#,dy#,dz# )

 Local vx#,vy#,vz#
 vx# = dx# - px#
 vy# = dy# - py#
 vz# = dz# - pz#
 Return Float(Sqr( vx# * vx# + vy# * vy# + vz# * vz# ))
End Function

Function DistancePointLine( ax#,ay#,az#,bx#,by#,bz#,px#,py#,pz# )

 Local LineMag#,U#
 Local ix#,iy#,iz#
 Local Distance#
 LineMag# = Magnitude( bx#, by#, bz#, ax#, ay#, az# )
 U# = ( ( ( px# - ax# ) * ( bx# - ax# ) ) +( ( py# - ay# ) * ( by# - ay# ) ) +( ( pz# - az# ) * ( bz# - az# ) ) ) /( LineMag# * LineMag# )

 If  U# < 0.0 Or U# > 1.0 Then Return False 
 ' closest point does Not fall within the line segment
 
 ix# = ax# + U# * ( bx# - ax# )
 iy# = ay# + U# * ( by# - ay# )
 iz# = az# + U# * ( bz# - az# )
 Distance# = Magnitude( px#,py#,pz#,ix#,iy#,iz# )
 Return True
End Function


i'll add that to the archives here in a bit.


Leon Drake(Posted 2007) [#44]
ok lolz got it fixed now, should be good to split those edges and return changed faces based on the booleans sent to the world type.




Leon Drake(Posted 2007) [#45]
PROGRESS REPORT

ok i got it so it splits the edges along the intersection points, now i just have to have it split the faces on the intersection points of the other mesh and that should do it.




N(Posted 2007) [#46]
Try something other than a cube.


_33(Posted 2007) [#47]
In my mind, this csg stuff is extremely complex. Much more so than wrapping something that has been tested and that works, plainly. But I respect people that are obsessed about making something work.

Hope all the best! My game project will eventually need csg. But, csg that is compatible with stencil shadow. So that means, a soldered closed mesh.


Leon Drake(Posted 2007) [#48]
hmm later on i'll try a sphere on sphere instead.

but i noticed i need to use a different method for detecting a ray intersecting the triangle. currently this only detects the ray going a particular direction.


Russell(Posted 2007) [#49]
Imagine on the Amiga had one of the best boolean functions I've ever seen. Slow, but 99% accurate ;)

Russell


Leon Drake(Posted 2007) [#50]
cool. so the story goes so far. trying to find a bug where a couple edges get skipped in the intersection routine. tried sphere on sphere cone on cone and those on cubes too, it shows the intersections just not all of them. somewhere i did something that causes it to skip an Edge.

Just to be sure i tried b3d line pick on one triangle and got the same results.

so once i figure that out i can move on to the next part. ugh, this has turned into a more challenging task than i presumed.


Leon Drake(Posted 2007) [#51]
Well I finally got it working somewhat, I think i may have made a typo when checking to see whether or not a triangle intersects another triangle, it keeps returning true for all of them. I'll get to that but i just now got everything to carve correctly, except when i use sphere's or anything really high poly. As you can see below it leaves some small holes around the edges. But hey at least this is math only written in native Max code, so its not 3d lib or OS dependant.




BlitzSupport(Posted 2007) [#52]
Ooh, nice.


Leon Drake(Posted 2007) [#53]
now im just playing around with co-planar faces, should it stay or should it go bum ba bum bum ba.


Leon Drake(Posted 2007) [#54]
thats kind of odd bbcreatesphere(8) looks just like bbcreatesphere(16) also in B3dsdk it said the minimum was 8 so i tried 4 for the hell of it and it looked like bbcreatesphere(8) back on B3d.

Anyways fixed the detection issue and got it to carve a sphere
using the bbcreatesphere(4) with no probs.



And it carved in 225 milliseconds woot!
however the other one carved in like 3126 milliseconds.

Well this works great so far if the convex brushes are low-ish poly. If you guys want i can package it up as a module. i still need to document it and add a Minib3d example as well.


Leon Drake(Posted 2007) [#55]
Doh i forgot to show i got union working as well.

however what you see is still 3 meshes, this library doesnt actually combine meshes together it just chops each one accordingly. in fact you can make a call to the read out function to return the original mesh instead.



the only downside right now is i haven't written any functions to move or rotate brushes so you'd have to rebuild the brush for that. This library is very dependant on the order in which brushes are added. If a subtraction brush is added after a union brush it will cut the union brush, but if the subtraction was added before then then union brush will be ignored.

This library Performs CSG 3 ways, you can have it perform CSG on One single brush all other brushes will be ignored.
You can Set it to do a normal CSG operation carving or union on any brushes that it intersects with. Or you can do an entire world rebuild. Usually the case if you have to move pre-existing brushes around.

Here soon i wanna try my hand at adding some lightmapping functions to this library.


_33(Posted 2007) [#56]
- I think the performance figure you stated clearly shows this library can't do realtime CSG
- If you add 2 meshes, the result should return 1 mesh, because you want the solid mesh to be...solid! This is for many reasons, one could be a stencil shadow system.
- The textures should be applied to the new mesh accordingly to what the CSG function gives after it performed, specially not to confuse the calling application.
- From an application standpoint, a CSG lib should give the options to return what the application needs, not the other way around.

I can't help much but I just wish you luck if you want to do something usable by many.


BlitzSupport(Posted 2007) [#57]

If you guys want i can package it up as a module


Yes, please!

[Edit: Oops, I see you've posted it here. Thanks for sharing!]


Leon Drake(Posted 2007) [#58]
i designed it to return the Unions and Subtractions as seperate meshes yes. you could literally perform a CSG operation between two brushes only then simply add one brush to the other from the output.

The reason i did it this way is to reduce CSG operation time when using multiple brushes. there are many ways to use the CSG functions.

one is to do CSG on one brush singly, or Do CSG on That brush + any brushes it intersects, and finally you can Perform CSG on All Brushes doing a world rebuild.

I have a flag you can set to tel it whether to build dynamically or not. Dynamic off builds faster but has a tendency to not be quite as accurate in some situations. Dynamic on is slower but it gives you accurate results, best to use dynamic on a particular brush you are having problems with. e.g.

brush1.CSG(recursive=false,dynamic=false)
brush2.CSG(recursive=false,dynamic=true)
or
world.Rebuild(dynamic=true)



If you need to Just add one brush to another brush in the output to get one solid mesh. just do bbaddmesh or the minib3d equivalent.

As far as speed issues go, if the dynamic flag is off it generally can perform CSG in under a second. I didnt design this to be realtime, since it was primarily for one of my editors. I think a good approach to Realtime CSG would be something like using frustrum culling on intersecting brushes. Or a BSP method using culling portals.


On another note, how would i reapply textures to the returned mesh without first including a 3d library to do so. i can have it store the texture or brush handle on the surface, but the repainting cannot be done in the library otherwise it will be 3d lib dependant.


Wayne(Posted 2007) [#59]
Nice work Leon


_33(Posted 2007) [#60]
Sorry Leon didn't want to sound harsh or anything. Obviously I wish for all the bells and whistles, but this is already something nicely done.


Leon Drake(Posted 2007) [#61]
its all good after this i want to tackle Lightmapping and BSP.

I did include an example on how to return the Tbrush back into a textured mesh, i also added extra variables on the surface to store Surface brushes as either an int or a Type object. I have to make the read in out functions externally.


Leon Drake(Posted 2007) [#62]
here is a shot using 4 brushes - 2 union 2 subtraction




JoshK(Posted 2007) [#63]
You might like this paper I wrote:
http://www.leadwerks.com/files/csg.pdf


Leon Drake(Posted 2007) [#64]
thats exactly what inspired me to continue, actually after reading that the whole process became much clearer.


Leon Drake(Posted 2007) [#65]
In case anyone didnt notice i released the WIP module for this here


http://www.vigilart.com/vas.csg.zip