Findong out which way a triangle is pointing

Blitz3D Forums/Blitz3D Programming/Findong out which way a triangle is pointing

gburgess(Posted 2007) [#1]
This is one of those questions that I think everyone knows the answer to except me. I'm currently looking into doing dynamic damage effects for spaceships, and I've decided on a method. If it works out, you all get free screenshots ;)

So, I'm going to be removing triangles from spaceship meshes (I hope...) but before I do I'd like to generate some debris as though part of the hull is being "blasted out". To do that, I'll need to know which direction to throw debris in.

I guess I can start with the centrepoint of the triangle, which will be the average of it's three vertices, right? Okay, then. Now I need to know what direction to throw the debris in. Is there some way I can get that, maybe in the form of a vector?

EDIT: Oops, comedy "dong" reference in the thread title. Apparently can't change it with the edit function so you're all stuck with it. This is just to let you know that. And to let you know that I know. So now you know that I know, and I know that you know that I know.


bytecode77(Posted 2007) [#2]
e0x# = v3x# - v2x#
e0y# = v3y# - v2y#
e0z# = v3z# - v2z#
e1x# = v2x# - v1x#
e1y# = v2y# - v1y#
e1z# = v2z# - v1z#

normal_x# = (e0y# * e1z# - e0z# * e1y#)
normal_y# = (v1y# - light_y#) * (e0z# * e1x# - e0x# * e1z#)
normal_z# = (v1z# - light_z#) * (e0x# * e1y# - e0y# * e1x#)


v1x v1y v1z, v2x v2y... are the triangle coordinates.
nx ny nz are the normals.

also for some uses you need to normalize it. that means to make the vector exact 1 meter long.

do# = sqr(nx#^2+ny#^2+nz#^2)
nx#=nx#/do#
ny#=ny#/do#
nz#=nz#/do#



big10p(Posted 2007) [#3]
Also, you may be able to hack something useful out of this code:

http://www.blitzbasic.com/codearcs/codearcs.php?code=680


bytecode77(Posted 2007) [#4]
that source code is too long to be understood.

what you need is a particle engine
http://www.blitzbasic.com/toolbox/toolbox.php?tool=174


Ricky Smith(Posted 2007) [#5]
One "easy" way is to use linepicks or camerapicks for your "shots" and just use the PickedNX#(),PickedNY#() and PickedNZ#() functions to get the normals of the picked tri.


Stevie G(Posted 2007) [#6]

So, I'm going to be removing triangles from spaceship meshes (I hope...) but before I do I'd like to generate some debris as though part of the hull is being "blasted out". To do that, I'll need to know which direction to throw debris in.



To remove a single triangle you need to rebuild the whole mesh and omit said triangle so it could be very slow.

I'd recommend using a particle engine ( not necessarily devils as there are loads about ). The general idea would be to create an emitter at the point of contact, align it to the contact normal vector and spew some particles from the emitter.

How are you determining which triangle you've hit in the first place?

Stevie


bytecode77(Posted 2007) [#7]
actually, i dont see the reason why you sould use triangle explosion...
use a particle system!


gburgess(Posted 2007) [#8]
Okay, just to be clear:

I have a perfectly good particle system, creating explosions in the right areas. However, yesterday I was inspired by this screen shot:

http://fileanchor.com/84119.jpeg

Specifically, the ship near the bottom with the holes, and I suddenly realised how it was done. Should've occurred to me sooner, having played Bridge Commander years ago, but there you go.

Since my initial post in this thread, I've written the code that turns polygons progressively darker, the more damage they take. Ones that turn black completely are them removed. The black vertexes left behind on the adjacent polys will then create the scorch effect seen in the screenshot.

I've got all this working just fine now.

However, I was wondering about attaching firey particle-emitters to the areas that had been blasted away, and possibly some debris to go with the initial removal of polys. And, for this, I need to know where the middle of a given poly lies.

Thanks for all the advice, guys. I have, however, just got one question which should help me understand a lot of it:

What's a normal?


Matty(Posted 2007) [#9]
A normal is a vector which is perpendicular to a plane. So in the case of polygons in 3d models a normal is a vector which is perpendicular to a particular triangle. Usually the normal is 'normalised' to be length '1' (ie a unit vector).


gburgess(Posted 2007) [#10]
Ah, right. So I'm basically looking for the normal of a given poly, then? Hmm, I'm surprised there's no built-in command for that in Blitz3D.

Oh well, thanks for the info, guys!


Gabriel(Posted 2007) [#11]
Well there kind of is. Each vertex has a normal, so I guess you could retrieve the vertex normal of each of the three vertices and average it for a poly normal? Would that work?

Check out VertexNX() VertexNY() and VertexNZ() in the docs, I think. Sorry I can't be more specific, but I don't have B3D installed at the moment and my CD appears to have died on me.


gburgess(Posted 2007) [#12]
Ahh, yes, I saw those yesterday. Right, that sounds like it should works. Thanks!


big10p(Posted 2007) [#13]
Well there kind of is. Each vertex has a normal, so I guess you could retrieve the vertex normal of each of the three vertices and average it for a poly normal? Would that work?
No, unfortunately. Since vert normals are smoothed between all connected tris, these normals could feasibly be pointing in just about any direction.

[edit]


gburgess(Posted 2007) [#14]
Oh, okay.


big10p(Posted 2007) [#15]
Just use the cross product method to calc surface normals, as shown in this code:
http://www.blitzbasic.com/codearcs/codearcs.php?code=976


gburgess(Posted 2007) [#16]
Oh I wish I had a better grasp on maths. I dunno what other people read, but all I saw was:

"Just use the BLLEEAAAUUGGGHHHHHH to calc surface normals"

Seriously, that code seems much longer than what Devil posted near the top. This one also seems to calculate stuff for an entire mesh. Are either of the two examples better in any way?


big10p(Posted 2007) [#17]
Heh, don't worry about the math - you don't need to know how it works, just that it does work. :)

OK, I've chopped the code down into a simple function to calculate the surface normal of a triangle:
Global result_nx#, result_ny#, result_nz#

; Given the 3 vertex positions of a triangle, this function calculates
; the surface normal of the defined triangle, and returns the result via
; the global variables result_nx#, result_ny# and result_nz#.
; Note that the 3 vertex positions must be supplied to this function in
; clockwise order to get the correct result.
Function calc_surf_normal(v0x#,v0y#,v0z#, v1x#,v1y#,v1z#, v2x#,v2y#,v2z#)

	; Get the vectors for two edges of the triangle.
	vec1x# = v0x# - v1x#
	vec1y# = v0y# - v1y#
	vec1z# = v0z# - v1z#
	
	vec2x# = v1x# - v2x#
	vec2y# = v1y# - v2y#
	vec2z# = v1z# - v2z#
	
	; Compute their cross product.
	x# = vec1y# * vec2z# - vec1z# * vec2y#
	y# = vec1z# * vec2x# - vec1x# * vec2z#
	z# = vec1x# * vec2y# - vec1y# * vec2x#

	; Normalize vector.
	l# = Sqr(x# * x# + y# * y# + z# * z#)
	
	result_nx# = x# / l#
	result_ny# = y# / l#
	result_nz# = z# / l#

End Function


I haven't tested this but it should work (famous last words).


gburgess(Posted 2007) [#18]
You're a hero. I won't be able to try it until next week, because I'm travelling to Ireland to fix my aunt's computer. I kid you not.

Thanks again!


big10p(Posted 2007) [#19]
No problem, but save the thanks until you get back and can confirm it works! :p


bytecode77(Posted 2007) [#20]
big10p: i already posted one:

e0x# = v3x# - v2x#
e0y# = v3y# - v2y#
e0z# = v3z# - v2z#
e1x# = v2x# - v1x#
e1y# = v2y# - v1y#
e1z# = v2z# - v1z#

normal_x# = (e0y# * e1z# - e0z# * e1y#)
normal_y# = (v1y# - light_y#) * (e0z# * e1x# - e0x# * e1z#)
normal_z# = (v1z# - light_z#) * (e0x# * e1y# - e0y# * e1x#)



v1x v1y v1z, v2x v2y... are the triangle coordinates.
nx ny nz are the normals.

also for some uses you need to normalize it. that means to make the vector exact 1 meter long.

do# = sqr(nx#^2+ny#^2+nz#^2)
nx#=nx#/do#
ny#=ny#/do#
nz#=nz#/do#



big10p(Posted 2007) [#21]
That's not a function.

Also, I have no idea what's going on here:

normal_x# = (e0y# * e1z# - e0z# * e1y#)
normal_y# = (v1y# - light_y#) * (e0z# * e1x# - e0x# * e1z#)
normal_z# = (v1z# - light_z#) * (e0x# * e1y# - e0y# * e1x#)




Stevie G(Posted 2007) [#22]

Also, I have no idea what's going on here:


normal_x# = (e0y# * e1z# - e0z# * e1y#)
normal_y# = (v1y# - light_y#) * (e0z# * e1x# - e0x# * e1z#)
normal_z# = (v1z# - light_z#) * (e0x# * e1y# - e0y# * e1x#)





Agree, that light x/y stuff will have no bearing on the calculated normal so it makes no sense, even if the cross product portion is correct.

Stevie


Gabriel(Posted 2007) [#23]
No, unfortunately. Since vert normals are smoothed between all connected tris, these normals could feasibly be pointing in just about any direction.


I realise that, but they can't be pointing in "just about any direction" as they are only joined to triangles with which they share a smoothing group. Thus they are already being lit to smooth across that join and I would argue that the averaged normal is a closer approximation of the direction the surface *appears* to be facing than the true normal of the triangle.


big10p(Posted 2007) [#24]
I realise that, but they can't be pointing in "just about any direction" as they are only joined to triangles with which they share a smoothing group. Thus they are already being lit to smooth across that join and I would argue that the averaged normal is a closer approximation of the direction the surface *appears* to be facing than the true normal of the triangle.
OK, I admit saying "just about any direction" was overstating things a bit, but I simply assumed Glenny-boy wanted the 'true' direction of the tri. I'm still sceptical that averaging normals will work in any meaningful way. I'm prepared to be proved wrong, though. :)


bytecode77(Posted 2007) [#25]
oh sorry, i forgot to take that light x/y by stealing the code from my shadow system :o