def pointInTri2D(v, v1, v2, v3): global dict_matrix key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y # Commented because its slower to do teh bounds check, we should realy cache the bounds info for each face. ''' # BOUNDS CHECK xmin= 1000000 ymin= 1000000 xmax= -1000000 ymax= -1000000 for i in (0,2,4): x= key[i] y= key[i+1] if xmax<x: xmax= x if ymax<y: ymax= y if xmin>x: xmin= x if ymin>y: ymin= y x= v.x y= v.y if x<xmin or x>xmax or y < ymin or y > ymax: return False # Done with bounds check ''' try: mtx = dict_matrix[key] if not mtx: return False except: side1 = v2 - v1 side2 = v3 - v1 nor = side1.cross(side2) l1 = [side1[0], side1[1], side1[2]] l2 = [side2[0], side2[1], side2[2]] l3 = [nor[0], nor[1], nor[2]] mtx = Matrix(l1, l2, l3) # Zero area 2d tri, even tho we throw away zerop area faces # the projection UV can result in a zero area UV. if not mtx.determinant(): dict_matrix[key] = None return False mtx.invert() dict_matrix[key] = mtx uvw = (v - v1) * mtx return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1
def pointInTri2D(v, v1, v2, v3): global dict_matrix key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y # Commented because its slower to do teh bounds check, we should realy cache the bounds info for each face. """ # BOUNDS CHECK xmin= 1000000 ymin= 1000000 xmax= -1000000 ymax= -1000000 for i in (0,2,4): x= key[i] y= key[i+1] if xmax<x: xmax= x if ymax<y: ymax= y if xmin>x: xmin= x if ymin>y: ymin= y x= v.x y= v.y if x<xmin or x>xmax or y < ymin or y > ymax: return False # Done with bounds check """ try: mtx = dict_matrix[key] if not mtx: return False except: side1 = v2 - v1 side2 = v3 - v1 nor = side1.cross(side2) l1 = [side1[0], side1[1], side1[2]] l2 = [side2[0], side2[1], side2[2]] l3 = [nor[0], nor[1], nor[2]] mtx = Matrix(l1, l2, l3) # Zero area 2d tri, even tho we throw away zerop area faces # the projection UV can result in a zero area UV. if not mtx.determinant(): dict_matrix[key] = None return False mtx.invert() dict_matrix[key] = mtx uvw = (v - v1) * mtx return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1
def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid = False): # Constant function variables p = mouseViewRay.p d = mouseViewRay.d for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example) win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices'] # calculate a few geometric extents for this window win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5 win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5 win_size_x = (win_max_x - win_min_x + 1.0) * 0.5 win_size_y = (win_max_y - win_min_y + 1.0) * 0.5 #useMid is for projecting the coordinates when we subdivide the screen into bins if useMid: # == True screen_x = win_mid_x screen_y = win_mid_y # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one... if (win_max_x > screen_x > win_min_x) and ( win_max_y > screen_y > win_min_y): # first we handle all pending events for this window (otherwise the matrices might come out wrong) Window.QHandle(win3d['id']) # now we get a few matrices for our window... # sorry - i cannot explain here what they all do # - if you're not familiar with all those matrices take a look at an introduction to OpenGL... pm = Window.GetPerspMatrix() # the prespective matrix pmi = Matrix(pm); pmi.invert() # the inverted perspective matrix if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon): # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5) hms = mouseViewRay.hms ortho_d = mouseViewRay.ortho_d # ortho mode: is a bit strange - actually there's no definite location of the camera ... # but the camera could be displaced anywhere along the viewing direction. ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector() ortho_d.w = 0 # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction #hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0 hms[:] = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0 # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1 p=(hms*pmi) + (1000*ortho_d) p.resize3D() d[:] = ortho_d[:3] # Finally we shift the position infinitely far away in # the viewing direction to make sure the camera if outside the scene # (this is actually a hack because this function # is used in sculpt_mesh to initialize backface culling...) else: # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location vmi = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix fp = mouseViewRay.fp dx = pm[3][3] * (((screen_x-win_min_x)/win_size_x)-1.0) - pm[3][0] dy = pm[3][3] * (((screen_y-win_min_y)/win_size_y)-1.0) - pm[3][1] fp[:] = \ pmi[0][0]*dx+pmi[1][0]*dy,\ pmi[0][1]*dx+pmi[1][1]*dy,\ pmi[0][2]*dx+pmi[1][2]*dy # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y) #- figuring out how to calculate this took me quite some time. # The calculation of dxy and fp are simplified versions of my original code #- so it's almost impossible to explain what's going on geometrically... sorry p[:] = vmi[3][:3] # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp)) d[:] = p.x-fp.x, p.y-fp.y, p.z-fp.z #print 'd', d, 'p', p, 'fp', fp # the direction vector is simply the difference vector from the virtual camera's position #to the unprojected (screenspace) point fp # Do we want to return a direction in object's localspace? if localMatrix: localInvMatrix = Matrix(localMatrix) localInvMatrix.invert() localInvMatrix_notrans = localInvMatrix.rotationPart() p = p * localInvMatrix d = d * localInvMatrix # normalize_v3 # remove the translation from d d.x -= localInvMatrix[3][0] d.y -= localInvMatrix[3][1] d.z -= localInvMatrix[3][2] d.normalize() ''' # Debugging me = Blender.Mesh.New() me.verts.extend([p[0:3]]) me.verts.extend([(p-d)[0:3]]) me.edges.extend([0,1]) ob = Blender.Scene.GetCurrent().objects.new(me) ''' return True, p, d # Origin, Direction # Mouse is not in any view, return None. return False, None, None
def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid=False): # Constant function variables p = mouseViewRay.p d = mouseViewRay.d for win3d in Window.GetScreenInfo( Window.Types.VIEW3D ): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example) win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices'] # calculate a few geometric extents for this window win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5 win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5 win_size_x = (win_max_x - win_min_x + 1.0) * 0.5 win_size_y = (win_max_y - win_min_y + 1.0) * 0.5 #useMid is for projecting the coordinates when we subdivide the screen into bins if useMid: # == True screen_x = win_mid_x screen_y = win_mid_y # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one... if (win_max_x > screen_x > win_min_x) and (win_max_y > screen_y > win_min_y): # first we handle all pending events for this window (otherwise the matrices might come out wrong) Window.QHandle(win3d['id']) # now we get a few matrices for our window... # sorry - i cannot explain here what they all do # - if you're not familiar with all those matrices take a look at an introduction to OpenGL... pm = Window.GetPerspMatrix() # the prespective matrix pmi = Matrix(pm) pmi.invert() # the inverted perspective matrix if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon): # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5) hms = mouseViewRay.hms ortho_d = mouseViewRay.ortho_d # ortho mode: is a bit strange - actually there's no definite location of the camera ... # but the camera could be displaced anywhere along the viewing direction. ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector() ortho_d.w = 0 # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction #hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0 hms[:] = (screen_x - win_mid_x) / win_size_x, ( screen_y - win_mid_y) / win_size_y, 0.0, 1.0 # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1 p = (hms * pmi) + (1000 * ortho_d) p.resize3D() d[:] = ortho_d[:3] # Finally we shift the position infinitely far away in # the viewing direction to make sure the camera if outside the scene # (this is actually a hack because this function # is used in sculpt_mesh to initialize backface culling...) else: # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location vmi = Matrix(Window.GetViewMatrix()) vmi.invert() # the inverse viewing matrix fp = mouseViewRay.fp dx = pm[3][3] * (( (screen_x - win_min_x) / win_size_x) - 1.0) - pm[3][0] dy = pm[3][3] * (( (screen_y - win_min_y) / win_size_y) - 1.0) - pm[3][1] fp[:] = \ pmi[0][0]*dx+pmi[1][0]*dy,\ pmi[0][1]*dx+pmi[1][1]*dy,\ pmi[0][2]*dx+pmi[1][2]*dy # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y) #- figuring out how to calculate this took me quite some time. # The calculation of dxy and fp are simplified versions of my original code #- so it's almost impossible to explain what's going on geometrically... sorry p[:] = vmi[3][:3] # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp)) d[:] = p.x - fp.x, p.y - fp.y, p.z - fp.z #print 'd', d, 'p', p, 'fp', fp # the direction vector is simply the difference vector from the virtual camera's position #to the unprojected (screenspace) point fp # Do we want to return a direction in object's localspace? if localMatrix: localInvMatrix = Matrix(localMatrix) localInvMatrix.invert() localInvMatrix_notrans = localInvMatrix.rotationPart() p = p * localInvMatrix d = d * localInvMatrix # normalize_v3 # remove the translation from d d.x -= localInvMatrix[3][0] d.y -= localInvMatrix[3][1] d.z -= localInvMatrix[3][2] d.normalize() ''' # Debugging me = Blender.Mesh.New() me.verts.extend([p[0:3]]) me.verts.extend([(p-d)[0:3]]) me.edges.extend([0,1]) ob = Blender.Scene.GetCurrent().objects.new(me) ''' return True, p, d # Origin, Direction # Mouse is not in any view, return None. return False, None, None