Get Face from raycast?

how do I get the center of a face using raycast?

attached is the file I am making

the code I need will replace line 38 - > Dist=Ray[0].worldPosition-Ray[1]

right now I am getting the distance from the ray hitpoint to the center of the object,

I need the distance from the center of the object to the center of the face.

thanks!

Attachments

Placeblock.blend (525 KB)

Get the hit polygon and take the average of the world positions of the vertices.

yeah, but hitPoly only works on triangle meshes right?

what about getting the face normals for all faces, and then checking to see which face has the same normal and is closest to the hitPoint?

<b>from</b> <b>bge</b> <b>import</b> logic
cont = logic.getCurrentController()
object = cont.owner

<b>for</b> mesh <b>in</b> object.meshes:
   <b>for</b> m_index <b>in</b> range(len(mesh.materials)):
      <b>for</b> v_index <b>in</b> range(mesh.getVertexArrayLength(m_index)):
         vertex = mesh.getVertex(m_index, v_index)
         ##now how do I compute the face normal?

        

If you want the hit point to match the mesh topology, use triangle mesh.

got it,

I can add the triangle mesh duplicate, do the raycast, then delete the duplicate,

thanks goose.

ok, I have the polyProxy how do I loop through it’s vericies and get the average?

ok, I am close but I seem to be doing something wrong

a bit of help?


import bge


from mathutils import Vector
def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    MOA = cont.sensors['MOA']
    LeftClick = cont.sensors['Mouse1']
    scene = bge.logic.getCurrentScene()
    cam = scene.objects['Empty']
    timer = cont.sensors['Timer']
    if timer.positive:
        if MOA.positive and not LeftClick.positive:
            cam.alignAxisToVect(MOA.hitPosition-cam.worldPosition,0,1)
            D=cam.getDistanceTo(MOA.hitPosition)+.1
            Ray = cam.rayCast(cam.worldPosition+(cam.worldOrientation.col[0]*D),cam.worldPosition,0,'',0,0,0)
            bge.render.drawLine(cam.worldPosition,MOA.hitPosition,(1,0,0))
            
            if Ray[0]:
                ##print(Ray[0])  
                added = scene.addObject('HL',own,1)
                added.worldPosition=Ray[0].worldPosition
                added.alignAxisToVect(Vector(Ray[2]),0,1)
                added.worldPosition=added.worldPosition+(added.worldOrientation.col[0]*2)
                
            
        if MOA.positive and LeftClick.positive and own['timer']==0:
            
            cam.alignAxisToVect(MOA.hitPosition-cam.worldPosition,0,1)
            D=cam.getDistanceTo(MOA.hitPosition)+.1
            Ray = cam.rayCast(cam.worldPosition+(cam.worldOrientation.col[0]*D),cam.worldPosition,0,'',0,0,0)
            
            if Ray[0] and own['timer']==0:
                TMesh= scene.addObject(MOA.hitObject['Tmesh'],MOA.hitObject,1)
                Ray2 = cam.rayCast(cam.worldPosition+(cam.worldOrientation.col[0]*D),cam.worldPosition,0,'TMESH',0,1,1)
                if Ray2[0]:
                    Poly = Ray2[3]
                    print(Ray2[0])  
                    added = scene.addObject('PlaceBlock',own,0)
                    added.worldPosition=Ray[0].worldPosition
                    added.alignAxisToVect(Vector(Ray[2]),0,1)
                    print("PolyProxy is "+str(Ray2[3]))
                    
                    v=[0,0,0]
                    v1=Ray2[3].v1
                    v2=Ray2[3].v2
                    v3=Ray2[3].v3
                    if Ray2[3].v4:
                        v4=Ray2[3].v4
                        L=[v1,v2,v3,v4]
                    else:
                        L=[v1,v2,v3]
                    avg=Vector([0,0,0])    
                    for Vert in L:
                        for mesh in Ray2[0].meshes:
                            vertex = mesh.getVertex(0, Vert)
                            avg+=Vector(vertex.XYZ)
                    if Ray2[3].v4:
                        avg = avg*.25
                    else:
                        avg = avg*(1/3)            
                            
         ##now how do I compute the face normal?                           
                            
                        
                        
                    
                    Dist=Ray[0].worldPosition-avg
                    print(Dist)
                    added.worldPosition=added.worldPosition+(added.worldOrientation.col[0]*Dist.magnitude)
                    added.worldPosition=added.worldPosition+(added.worldOrientation.col[0]*added['offset'])
                    V2=Ray[2]
                    
                    
                    
                    
                    
                    own['timer']=30
            


main()




Attachments

Placeblock.blend (547 KB)

ok I am really close, but for some reason

  1. randomly it spawns the block inside the object

  2. the distance is not consistent?


import bge


from mathutils import Vector
def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner


    MOA = cont.sensors['MOA']
    LeftClick = cont.sensors['Mouse1']
    scene = bge.logic.getCurrentScene()
    cam = scene.objects['Empty']
    timer = cont.sensors['Timer']
    if timer.positive:
        if MOA.positive and not LeftClick.positive:
            cam.alignAxisToVect(MOA.hitPosition-cam.worldPosition,0,1)
            D=cam.getDistanceTo(MOA.hitPosition)+.1
            Ray = cam.rayCast(cam.worldPosition+(cam.worldOrientatio  n.col[0]*D),cam.worldPosition,0,'Tmesh',0,0,0)
            bge.render.drawLine(cam.worldPosition,MOA.hitPosit  ion,(1,0,0))
            
            if Ray[0]:
                ##print(Ray[0])  
                added = scene.addObject('HL',own,1)
                added.worldPosition=Ray[0].worldPosition
                added.alignAxisToVect(Vector(Ray[2]),0,1)
                added.worldPosition=added.worldPosition+(added.wor  ldOrientation.col[0]*2)
                
            
        if MOA.positive and LeftClick.positive and own['timer']==0:
            
            cam.alignAxisToVect(MOA.hitPosition-cam.worldPosition,0,1)
            D=cam.getDistanceTo(MOA.hitPosition)+.1
            Ray = cam.rayCast(cam.worldPosition+(cam.worldOrientatio  n.col[0]*D),cam.worldPosition,0,'Tmesh',0,0,0)
            
            if Ray[0] and own['timer']==0:
                TMesh= scene.addObject(MOA.hitObject['Tmesh'],MOA.hitObject,0)
                Ray2 = cam.rayCast(cam.worldPosition+(cam.worldOrientatio  n.col[0]*D),cam.worldPosition,0,'TMESH',0,1,1)
                if Ray2[0]:
                    Poly = Ray2[3]
                    print(Ray2[0])  
                    added = scene.addObject('PlaceBlock',own,0)
                    added.worldPosition=Ray[0].worldPosition
                    added.alignAxisToVect(Vector(Ray[2]),0,1)
                    print("PolyProxy is "+str(Ray2[3]))
                    
                    v=[0,0,0]
                    v1=Ray2[3].v1
                    v2=Ray2[3].v2
                    v3=Ray2[3].v3
                    if Ray2[3].v4:
                        v4=Ray2[3].v4
                        L=[v1,v2,v3,v4]
                    else:
                        L=[v1,v2,v3]
                    avg=Vector([0,0,0])    
                    for Vert in L:
                        for mesh in Ray2[0].meshes:
                            vertex = mesh.getVertex(0, Vert)
                            avg+= Vector(MOA.hitObject.worldPosition+(MOA.hitObject.  worldOrientation*Vector(vertex.XYZ)))
                            avg*=.5
                         
                            
       
                        
                        
                    
                    Dist=MOA.hitObject.worldPosition-avg
                    print(Dist)
                    added.worldPosition=added.worldPosition+(added.wor  ldOrientation.col[0]*Dist.magnitude)
                    added.worldPosition=added.worldPosition+(added.wor  ldOrientation.col[0]*added['offset'])
                   
                    
                    
                    
                    
                    
                    own['timer']=30
                    TMesh.endObject()


main()



Attachments

Placeblock.blend (547 KB)

Got it!

floating point math was my enemy.

Attachments

PlaceblockWorking.blend (549 KB)