Author Topic: Scene vs world position and ray casting  (Read 248 times)

Chemistry

  • Newbie
  • *
  • Posts: 8
    • View Profile
Scene vs world position and ray casting
« on: February 13, 2018, 07:09:08 PM »
Hey,

Can anyone explain to me the difference between scene vs world position and how ray casting works? I've been tinkering with MMAPI and this just keeps leaving me stumped.

Thanks!

MagWeb

  • Administrator
  • Hero Member
  • *****
  • Posts: 1271
    • View Profile
Re: Scene vs world position and ray casting
« Reply #1 on: February 14, 2018, 04:07:48 AM »
Are you aware of the api documentation directory in your mm_api/distrib ? Open index.html...

Quote
Meshmixer internally re-scales imported meshes to a normalized coordinate space, ie a 2x2x2 unit box centered at the origin. API functions for spatial queries, bounding boxes, etc, currently expect points and dimensions in this normalized space, and return normalized results as well.

So if there's a single cube object with the world dimension of 25x25 mm centred at the origin its minimal 3D point would be x = -12.5, y = -12.5 and z = -12.5 .
Now internally MM uses scene coordinates  to calculate where the total cubic bounding box is 2 x 2 x 2.
In scene coordinates this minimal 3D point would be x = -1, y = -1 and z = -1 .

You need to use mm.convert module to convert form world to scene and vice versa.

......

Quote
mm.util.find_ray_hit(remote, ray_origin, ray_direction)
Find the intersection of a ray (specified by 3-tuples for origin and direction) and the 3D surface. Returns a tuple (bOK, hitFrame), where bOK is a boolean indicating if a hit was found, and hitFrame is an mmFrame at the hit point, with Z axis oriented to the surface normal

You need to define ray_origin and ray_direction in scene coordinates.
See example code demo_02_spatialtests.py



« Last Edit: February 14, 2018, 04:48:49 AM by MagWeb »
I'm just a user as you are. Being no Autodesk employee: I do not know where this road will lead to, nor do I claim to've all stuff got right.

Chemistry

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Scene vs world position and ray casting
« Reply #2 on: February 14, 2018, 08:16:36 PM »
Thanks MagWeb. I finally understand scene vs world and why the conversion changes.

In demo_02_spatialtests.py I am not getting the results I expect, and am not sure why. This example creates a ray from far away starts it at that point and then aims it towards my object along the Z+ axis towards the center of my bounding box correct?

 So if I import a cube and place the center at (0,0,0) with one of the faces lined up with the Z-axis  before running the example I would expect my result for where the ray hit to be something along the lines of (0,0,+Z) where +Z depends on the actual size of my cube.

Instead for a cube that is 10mm in each direction I am getting the result of :

hit:  True  world pos:  (-0.0029391050338745117, -0.0010218620300292969, -0.48660945892333984)


Wouldn't the world coordinates be expected to be (0,0,+5)?

This is really stumping me.

Thanks!!!!


Also on a side note. Can the measure tool be used through the API? for instance to tell how thick a piece of a model is? Thanks

« Last Edit: February 14, 2018, 09:51:50 PM by Chemistry »

MagWeb

  • Administrator
  • Hero Member
  • *****
  • Posts: 1271
    • View Profile
Re: Scene vs world position and ray casting
« Reply #3 on: February 15, 2018, 08:00:43 AM »
Don't know why RMS labeled this result with "world pos". Actually these are still scene coordinates for hitFrame.origin wasn't converted before.

So this should work instead:

Code: [Select]
print "hit: ", bHit, " scene pos: ", hitFrame.origin;
print "hit: ", bHit, " world pos: ", mm.to_world(r, hitFrame.origin);

This way I get that output of a 25mm cube:

Quote
scene bbox min:  (-1.0, -1.0, -1.0)
scene bbox max:  (1.0, 1.0, 1.0)
world bbox min:  (-12.5, -12.5, -12.5)
world bbox max:  (12.5, 12.5, 12.5)
one world unit in scene dimensions:  0.0799999982119


hit:  True  scene pos:  (0.0, 0.0, -1.0)
hit:  True  world pos:  (0.0, 0.0, -12.5)

Note: Seems to me that there's a little error tolerance in Align. So try it with some not-yet aligned object (e.g the default sphere or the attached cube.obj)

------

Yes, Measure can be called via the api (see: StoredCommands.h). But this make sense with a following user interaction only (or am I wrong?).
I'm just a user as you are. Being no Autodesk employee: I do not know where this road will lead to, nor do I claim to've all stuff got right.

MagWeb

  • Administrator
  • Hero Member
  • *****
  • Posts: 1271
    • View Profile
Re: Scene vs world position and ray casting
« Reply #4 on: February 15, 2018, 10:40:05 AM »
Or do you wonder about the resulting negative z-value?

The ray direction (ray_dir = (0.0,0.0,1.0)) points from a "far away" point towards growing z-values. Meaning the ray hits the surface at its side looking towards dropping values. You'll get (0,0,-5) in your case.
ray_dir = (0.0,0.0,-1.0) points from a "far away" point towards dropping z-values. Meaning the ray hits the surface at its side looking towards growing values. You'll get (0,0,5) in your case.
Sounds wired - simply a question of your point of view.

Don't worry about the ray origin here. "ray_origin = subv3(center, mulv3s(ray_dir, 25.0*max(diag)))" switches its position as the direction changes.
I'm just a user as you are. Being no Autodesk employee: I do not know where this road will lead to, nor do I claim to've all stuff got right.

MagWeb

  • Administrator
  • Hero Member
  • *****
  • Posts: 1271
    • View Profile
Re: Scene vs world position and ray casting
« Reply #5 on: February 16, 2018, 10:27:33 AM »
Here's an example of how to use a hitting ray to get measurements simply by calculating the distance of two 3D points:

Code: [Select]
#  Calculate distance between a ray's in- and out-hits
#  at a fixed direction (> ray_dir)
#  based on the surface normal

import mmapi
from mmRemote import *
import mm
from mm.mm_math import *
import math

# initialize connection
r = mmRemote()
r.connect()

# get object-space bounding box of selected object
(fMin,fMax) = mm.get_selected_bounding_box(r)

# construct a ray from far-away-pt through center of bbox
center = lerpv3(fMin, fMax, 0.5)
diag = subv3(fMax, fMin)
ray_dir = (1.0,0.0,0.0) # fixed direction (here e.g.: along x-axis)

# find hit "in" with "positive" ray direction:
ray_origin = subv3(center, mulv3s(ray_dir, 25.0*max(diag)))
(bHit, inFrame) = mm.find_ray_hit(r, ray_origin, ray_dir)
#print "in_hit: ", bHit, " world pos: ", mm.to_world(r, inFrame.origin), "world units" # uncomment to print output values
#mm.create_pivot(r, inFrame) # uncomment to visualize: drops a pivot at in-hit

# find hit "out" along ray with "negative" ray direction:
ray_origin = subv3(center, mulv3s(negv3(ray_dir), 25.0*max(diag)))
(cHit, outFrame) = mm.find_ray_hit(r, ray_origin, negv3(ray_dir))
#print "out_hit along ray: ", cHit, " out pos: ", mm.to_world(r, outFrame.origin), "world units" # uncomment to print output values
#mm.create_pivot(r, outFrame) # uncomment to visualize: drops a pivot at out along ray

# calculate distance between in and out hit along ray:
dist = math.sqrt((outFrame.origin[0] - inFrame.origin[0])**2 + (outFrame.origin[1] - inFrame.origin[1])**2 + (outFrame.origin[2] - inFrame.origin[2])**2)
print "distance along ray: ",  mm.to_world(r, dist), "world units"

# find hit "out" along in-hit's normal direction:
ray_dir = inFrame.z
ray_origin = subv3(inFrame.origin, mulv3s(ray_dir, 25.0*max(diag)))
(cHit, outFrame) = mm.find_ray_hit(r, ray_origin, ray_dir)
#print "out_hit along normal: ", cHit, " out pos: ", mm.to_world(r, outFrame.origin), "world units" # uncomment to print output values
#mm.create_pivot(r, outFrame) # uncomment to visualize: drops a pivot at out along in-hit's normal

# calculate distance between in and out hit along normal:
dist = math.sqrt((outFrame.origin[0] - inFrame.origin[0])**2 + (outFrame.origin[1] - inFrame.origin[1])**2 + (outFrame.origin[2] - inFrame.origin[2])**2)
print "distance along normal: ",  mm.to_world(r, dist), "world units"

#done!
r.shutdown()

The first result follows the ray while the second uses the in-hit's surface normal (see attached image)

« Last Edit: February 16, 2018, 10:33:22 AM by MagWeb »
I'm just a user as you are. Being no Autodesk employee: I do not know where this road will lead to, nor do I claim to've all stuff got right.

Chemistry

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Scene vs world position and ray casting
« Reply #6 on: February 17, 2018, 03:06:19 PM »
MagWeb,

This is amazing! Thank you so much for your example! This is so cool to see in action!