# Solved:Weard vertex buffer result after getting mesh info.

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:
``` 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,points,points) outbuff.append( physx.NxVec3( points, points, points ) ) else: vec = transform * ogre.Vector3(points,points,points) 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 ) #outbuff.append( l ) #outbuff.append( l ) 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] ], vertices[ indices[i] ], vertices[ indices[i] ], 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], vertices[i], vertices[i])) 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) ```

dermont

13-05-2010 00:03:13

You probably need to multiply your vertices by the entities parent scene node's transformation matrix, e.g for bullet:

``` class MeshShapeUtil: .... @staticmethod def GetIndicies ( indexData ) : outbuff = [] numTris = indexData.indexCount if numTris == 0 : return outbuff else : numTris /= 3 ibuf = indexData.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: l = ogre.getUint32 ( ogre.castAsVoidPtr ( address ), 3 ) address += ibuf.getIndexSize() * 3 else: l = ogre.getUint16 ( ogre.castAsVoidPtr ( address ), 3 ) address += ibuf.getIndexSize() * 3 outbuff.append(tuple(l)) ibuf.unlock() return outbuff @staticmethod def GetVerticies ( vertex_data, transform ) : 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 :) vec = transform * ogre.Vector3(points,points,points) outbuff.append(tuple((vec.x,vec.y,vec.z))) newaddress += vbuf.getVertexSize() vbuf.unlock() return outbuff #------------------------------------------ # TriMesh Shape #------------------------------------------ @staticmethod def createTriMeshShape(entity): vertices = [] faces = [] if entity.getMesh().sharedVertexData: vertices += MeshShapeUtil.GetVerticies( entity.getMesh().sharedVertexData, entity.getParentSceneNode()._getFullTransform() ) for m in range(entity.getMesh().numSubMeshes): sm = entity.getMesh().getSubMesh(m) if not sm.useSharedVertices: faces += MeshShapeUtil.GetIndicies ( sm.indexData ) vertices += MeshShapeUtil.GetVerticies ( sm.vertexData, entity.getParentSceneNode()._getFullTransform() ) else: faces += MeshShapeUtil.GetIndicies ( sm.indexData ) mTriMesh = bullet.btTriangleMesh() for ind in faces: v1 = vertices[ind] v2 = vertices[ind] v3 = vertices[ind] b1 = bullet.btVector3(v1,v1,v1) b2 = bullet.btVector3(v2,v2,v2) b3 = bullet.btVector3(v3,v3,v3) #print b1.x(),b1.y(),b1.z() mTriMesh.addTriangle(b1, b2, b3) useQuantizedAABB = True del vertices del faces return mTriMesh, bullet.btBvhTriangleMeshShape(mTriMesh, useQuantizedAABB) ```

Gurrier

13-05-2010 09:42:21

Good point. When I was posting the same problem at the oGre3D Help forum I tought about it and was thinking it didn't look at the scale, position and orientation of his node.

Anyway, going to look into your posted code and see what major differences there are.

Edit: It was that. Thanks for you code. It made it a bit easyer.