Gurrier
10-05-2010 16:07:05
EDIT: the code that Dermont provided is correct. I'll post my code here to just if someone wants to grab it.
Hey guys, a few days ago I needed more than just AABB raycasting. So I started converting the code from the ogre3D wiki to python:
http://89.151.96.106/wiki/index.php/Raycasting_to_the_polygon_level_(Mogre)
this is the c++ version:
http://89.151.96.106/wiki/index.php/Raycasting_to_the_polygon_level
EDIT: I actually had this code... this is it. Was in the physx Demo app.
But now for some reason when I get back my Vertice list the list is allways:
00:Vector3(0, 0, 0)
01:Vector3(-50, -50, -50)
02:Vector3(-50, 50, -50)
03:Vector3(50, 50, -50)
04:Vector3(50, -50, -50)
05:Vector3(-50, -50, 50)
06:Vector3(50, -50, 50)
07:Vector3(50, 50, 50)
08:Vector3(-50, 50, 50)
09:Vector3(-50, -50, -50)
10:Vector3(50, -50, -50)
11:Vector3(50, -50, 50)
12:Vector3(-50, -50, 50)
13:Vector3(50, -50, -50)
14:Vector3(50, 50, -50)
15:Vector3(50, 50, 50)
16:Vector3(50, -50, 50)
17:Vector3(50, 50, -50)
18:Vector3(-50, 50, -50)
19:Vector3(-50, 50, 50)
20:Vector3(50, 50, 50)
21:Vector3(-50, 50, -50)
22:Vector3(-50, -50, -50)
23:Vector3(-50, -50, 50)
24:Vector3(-50, 50, 50)
Even on different meshes, on different positions
then when I want to do an Intersect() on them:
It allways return no hits.
Is there someone that can point me ion the right direction?
Solution:
CGetMeshInfo class:
CRayCastFromPoint Class:
init:
Hey guys, a few days ago I needed more than just AABB raycasting. So I started converting the code from the ogre3D wiki to python:
http://89.151.96.106/wiki/index.php/Raycasting_to_the_polygon_level_(Mogre)
this is the c++ version:
http://89.151.96.106/wiki/index.php/Raycasting_to_the_polygon_level
EDIT: I actually had this code... this is it. Was in the physx Demo app.
But now for some reason when I get back my Vertice list the list is allways:
00:Vector3(0, 0, 0)
01:Vector3(-50, -50, -50)
02:Vector3(-50, 50, -50)
03:Vector3(50, 50, -50)
04:Vector3(50, -50, -50)
05:Vector3(-50, -50, 50)
06:Vector3(50, -50, 50)
07:Vector3(50, 50, 50)
08:Vector3(-50, 50, 50)
09:Vector3(-50, -50, -50)
10:Vector3(50, -50, -50)
11:Vector3(50, -50, 50)
12:Vector3(-50, -50, 50)
13:Vector3(50, -50, -50)
14:Vector3(50, 50, -50)
15:Vector3(50, 50, 50)
16:Vector3(50, -50, 50)
17:Vector3(50, 50, -50)
18:Vector3(-50, 50, -50)
19:Vector3(-50, 50, 50)
20:Vector3(50, 50, 50)
21:Vector3(-50, 50, -50)
22:Vector3(-50, -50, -50)
23:Vector3(-50, -50, 50)
24:Vector3(-50, 50, 50)
Even on different meshes, on different positions
then when I want to do an Intersect() on them:
for i in range(0, len(indices), 3):
dHit = ogre.Math.intersects(
mouseRay,
vertices[indices[i]],
vertices[indices[i+1]],
vertices[indices[i+2]],
True,
False
)
It allways return no hits.
Is there someone that can point me ion the right direction?
Solution:
CGetMeshInfo class:
def getVertices ( vertex_data, transform, convertToNx = True ) :
outbuff = []
# get the start of the element
posElem = vertex_data.vertexDeclaration.findElementBySemantic( ogre.VertexElementSemantic.VES_POSITION )
vbuf = vertex_data.vertexBufferBinding.getBuffer( posElem.getSource() )
# get the start of the actual buffer
vertex = vbuf.lock( ogre.HardwareBuffer.HBL_READ_ONLY )
# what we need is the actual address of the buffer, so we have to check if there's an offset as well
# the is basically what baseVertexPointerToElement does
newaddress = posElem.getOffset() + ogre.castAsInt( vertex ) # note the cast to int to get the address
for i in range ( vertex_data.vertexCount ):
points = ogre.getFloat( ogre.castAsVoidPtr ( newaddress ), 3 ) # note the getFloat and Cast back to a pointer :)
if convertToNx:
vec = CMathUtilities.toNxVec3(transform) * physx.NxVec3(points[0],points[1],points[2])
outbuff.append( physx.NxVec3( points[0], points[1], points[2] ) )
else:
vec = transform * ogre.Vector3(points[0],points[1],points[2])
outbuff.append(tuple((vec.x, vec.y, vec.z)))
newaddress += vbuf.getVertexSize()
vbuf.unlock()
return outbuff
def getIndices ( index_data ) :
outbuff = []
numTris = index_data.indexCount
if numTris == 0 : return outbuff
else : numTris /= 3
ibuf = index_data.indexBuffer
if ibuf.getType() == ogre.HardwareIndexBuffer.IT_32BIT:
Use32Bit = True
else: Use32Bit = False
buffer = ibuf.lock( ogre.HardwareBuffer.HBL_READ_ONLY )
address = ogre.castAsInt ( buffer )
for i in range( numTris ):
if Use32Bit:
val = ogre.getUint32 ( ogre.castAsVoidPtr ( address ), 3 )
address += ibuf.getIndexSize() * 3
else:
val = ogre.getUint16 ( ogre.castAsVoidPtr ( address ), 3 )
address += ibuf.getIndexSize() * 3
outbuff.append( tuple(val))
#outbuff.append( l[0] )
#outbuff.append( l[1] )
#outbuff.append( l[2] )
ibuf.unlock()
return outbuff
def getMeshInfo( entity, convertToNx = True ):
vertices = []
faces = []
if entity.getMesh().sharedVertexData:
vertices += CMeshUtilities.GetVerticies( entity.getMesh().sharedVertexData, entity.getParentSceneNode()._getFullTransform() )
for m in range( entity.getMesh().numSubMeshes ):
sm = entity.getMesh().getSubMesh( m )
if not sm.useSharedVertices:
faces += CMeshUtilities.getIndices ( sm.indexData)
vertices += CMeshUtilities.getVertices ( sm.vertexData, entity.getParentSceneNode()._getFullTransform(), convertToNx )
else:
faces += CMeshUtilities.GetIndicies ( sm.indexData )
return vertices, faces
getExtents = staticmethod( getExtents )
getIndices = staticmethod( getIndices )
getVertices = staticmethod( getVertices )
getMeshInfo = staticmethod( getMeshInfo )
CRayCastFromPoint Class:
def Cast(self, ray_scene_query, mousePos, viewport, camera, pCaller, sceneMan):
mouseRay = camera.getCameraToViewportRay(mousePos.x / viewport.getActualWidth(),
mousePos.y / viewport.getActualHeight())
self.m_SceneManager = sceneMan
print "MouseS: " + str(mouseRay.Direction)
print "MouseE: " + str(mouseRay.Origin)
self.m_pray_scene_query = ray_scene_query
if self.m_pray_scene_query:
self.m_pray_scene_query.Ray = mouseRay
rayresult = self.m_pray_scene_query.execute()
if len(rayresult) <= 0:
return None
else:
return None
closest_distance = -1.0
closest_result = ogre.Vector3.ZERO
vNormal = ogre.Vector3.ZERO
query_result = self.m_pray_scene_query.getLastResults()
for this_result in query_result:
##stop checking if we have found a raycast hit that is closer than all remaining entities
if (closest_distance >= 0.0) and (closest_distance < this_result.distance):
break
##only check this result if its a hit against an entity
if (this_result.movable.MovableType != None) and (this_result.movable.MovableType == "Entity"):
##get the entity to check
pentity = this_result.movable
##mesh data to retrieve
self.m_Vertex_count = 0 ## will get value from CGetMeshInformation()
self.m_Index_count = 0 ## will get value from CGetMeshInformation()
self.m_Vertices = [] ## will get value from CGetMeshInformation()
self.m_Indices = [] ## will get value from CGetMeshInformation()
vertices, indices = CMeshUtilities.getMeshInfo(pentity, False)
ncf = -1 ##new closest_found
##test for hitting individual triangles on the mesh
for i in range(0, len(indices)):
dHit = ogre.Math.intersects(
mouseRay,
vertices[ indices[i][0] ],
vertices[ indices[i][1] ],
vertices[ indices[i][2] ],
True,
False
)
#if it was a hit, check the closest
if dHit.first:
if (closest_distance < 0.0) or (dHit.second < closest_distance):
closest_distance = dHit.second
ncf = i
if ncf > -1:
closest_result = mouseRay.getPoint(closest_distance)
##if you don't need the normal, comment this out; you'll save some CPU cycles.
##first change back the tuple to a vector3
verticesList = []
for i in range(0, len(vertices)):
verticesList.append(ogre.Vector3(vertices[i][0], vertices[i][1], vertices[i][2]))
v1 = verticesList[ncf] - verticesList[ncf + 1]
v2 = verticesList[ncf + 2] - verticesList[ncf + 1]
vNormal = v1.crossProduct(v2)
vertices = None
indices = None
if closest_distance >= 0.0:
pCaller.m_Result = ogre.Vector3(closest_result.x, closest_result.y, closest_result.z)
pCaller.m_ResNormal = vNormal / vNormal.normalise()
"""
##visualizes the result
if not self.m_SceneManager.createSceneNode("marker"):
ent = self.m_SceneManager.createEntity("marker", "Cube.mesh")
node = self.m_SceneManager.getRootSceneNode().createChildSceneNode( "marker" )
node.attachObject(ent)
node.position = pCaller.m_Result
node.scale(0.25,0.25,0.25)
else:
self.m_SceneManager.getSceneNode("marker").position = pCaller.m_Result
"""
return rayresult
else:
return None
init:
##Polygon Level Raycast
self.m_pray_scene_query = self.m_SceneManager.createRayQuery(ogre.Ray(), self.m_SceneManager.WORLD_GEOMETRY_TYPE_MASK)
if not self.m_pray_scene_query:
return False
self.m_pray_scene_query.setSortByDistance(True)
self.m_pray_scene_query.setQueryMask(self.DATACARRIER_MASK)
from Framework.RayCast import CRayCastFromPoint
rayCast = CRayCastFromPoint()
result = rayCast.Cast(self.m_pray_scene_query, self.m_MousePos, self.m_Viewport, self.m_Camera, self, self.m_SceneManager)
print str(result)