Notifications
Clear all

[Closed] RayIntersect

I just wondering how to build the RayIntersect function manually?
Let’s assume that this isn’t already existed.

9 Replies

Thanks! seesms pretty complicated.
I’ll study this…
Didn’t knew how useful Barycentric coordinates is.

it’s pretty simple really…

[ol]
[li]transform the ray we’re testing into the local space of the mesh we are testing against/[/li][li]for all tri faces in the mesh test the ray against for an intersection[/li][li]if there’s an intersection compute it’s position and normal and transform back into world space[/li][li]return the intersection as ray otherwise undefined[/li][/ol]

so, the object’s faces are in some sort of array?
Hmm… how about building the Ray constructor?
can’t find the 3ds max sdk on my system…

still can’t understand some of the code.
#define EPSILON 0.0001f

never tried using EPSILON in C++, what it does?

int RayIntersect(Ray& ray, float& at, Point3& norm, int& fi, Point3& bary, Mesh *mesh)what’s with the & and * on the object?

for(int i = 0; i < nfaces ; ++i, ++face) is ++i == i++?

sorry if you don’t know C\C++ it will be a little cryptic.
the #define EPSILON 0.00001 is just a preprocessor macro constant where ever EPSILON appears in the code replace with the value 0.00001. * in C is a pointer and & is either the address of an object or a reference to an object (in this case a reference). and yes in this example ++i is the same as i++ though in other places it would be different.

in mxs something like this

(
  	fn rayIntersect mObj ry &t &norm &fi &bary =
  	(
  		numfaces = mObj.numfaces;
  		first = false;
  		for f = 1 to numfaces do
  		(
  			n = getfacenormal mObj f;
  			rn = dot ry.dir n;
  			
  			if not rn > -0.00001 then
  			(
  				face = getface mObj f;
  				d = dot	(getvert mObj face[1]) n;
  				a = (d - dot ry.pos n)/rn;
  				
  				if a > 0.0 and not first and a < t then
  				(
  					p = ry.pos + a * ry.dir;
  					bry = meshop.getBaryCoords mObj f p;
  					
  					if bry.x > 0.0 and bry.x < 1.0 and bry.y > 0.0 and bry.y < 1.0 and bry.z > 0.0 and bry.z < 1.0 and
  						abs (bry.x + bry.y + bry.z - 1.0f) < 0.00001 then
  					(	
  						first = true;
  						t = a;
  						fi = f;
  						norm = n;
  						bary = bry;
  					)
  				)
  			)
  		)
  		first;
  	)	
  
  	t = 999999999.0;
  	bary = norm  = [0,0,0]
  	fi = 0;
  	i = rayIntersect $sphere01 (ray $point01.pos $point01.dir) &t &norm &fi &bary
  	if i then
  		point pos:($point01.pos + t * $point01.dir) dir:norm;
  )

where $sphere01 is a mesh and $point01 defines our ray along it’s z-axis. the logic is reversed as mxs is slow with continue and exit inside loops. Also in mxs there’s no need to transform the rays in and out of local space as by default all mesh values are return in world space.

this seems working only on a ray… how to detect if the 2 mesh collide?
btw…where did you found the source code? Can’t find it in SDK documentation…

3 Replies
(@istan_velo)
Joined: 11 months ago

Posts: 0

This is definitively a total different task, if you want to do it efficiently (e.g. in realtime) for huge meshes. Even the ray intersection task requires additional tweaks for bigger meshes to improve speed. Such tasks fill many chapters of many books: convex, convace, building trees, oobs, aabb,…

(@greatveemon)
Joined: 11 months ago

Posts: 0

So I guess collision detection is not easy… which technique is the most optimal? I already heard of aabb though… but that means I need to create a lot of it with different sizes to detect if it is colliding.

(@istan_velo)
Joined: 11 months ago

Posts: 0

Which technique you can use, depends on the application. The math for collision detection is simple – just many optimized compares in a certain order. The trick is the sorting and the preparation. You could also take a look for instance to PhysX and use what is available there.