nathan75
05-11-2006 10:17:30
entity.boundingBox.setExtents(-100,-100,-100,100,100,100)
I try to use this fucntion to change the size of the boundingBox,
Howevery the boundingBox do not change.
Because I try to control the animation by AI. So most of the time, my mesh's direction is different from origion. Part of the mesh was out from the origional boundingBox.
Is there some function to set this change available?
Thank you very much!
dermont
05-11-2006 16:25:45
Though from your post I'm guessing that you want the bounding box to be updated dynamically which I don't think you can do.
For display you could create your own debug box. To retrieve vertices for an animated entity, you can do something like this:
def Extents(entity):
# this is required
entity.addSoftwareAnimationRequest(False)
for s in range(entity.numSubEntities):
vertices = entity.getSubEntityVertices(s)
Vertex retrieval by entity is based on code from OgreOde. Here's some example code using a cube mesh as a pseudo debug box. You'll want want to replace the cube mesh a manual object cube. Sorry I don't have time to update this. Press 'R' to see wireframe.
# This code is in the Public Domain.
from pyogre import ogre
import SampleFramework as sf
NUM_ROBOTS = 10
class SkeletalApplication(sf.Application):
def _createScene(self):
#print dir(ogre.DynamicLines)
sceneManager = self.sceneManager
camera = self.camera
ogre.Animation.setDefaultInterpolationMode(ogre.Animation.IM_SPLINE)
sceneManager.ambientLight = (0.5, 0.5, 0.5)
ogre.MeshManager.getSingleton().boundsPaddingFactor = 0.50
#Pre-load the mesh so that we can tweak it with a manual animation
mesh = ogre.MeshManager.getSingleton().load("robot.mesh", 'General')
entity = sceneManager.createEntity("Test", 'robot.mesh')
nd = sceneManager.rootSceneNode.createChildSceneNode((10, -50, -100))
nd.attachObject(entity)
nd.showBoundingBox = True
nd.yaw(ogre.Degree(45).valueRadians())
self.animationStates = []
self.animationSpeeds = []
entity = sceneManager.createEntity('robot' , 'robot.mesh')
skel = entity.skeleton
entity.boundingbox = True
nd = sceneManager.rootSceneNode.createChildSceneNode((0, 0, 0))
nd.attachObject(entity)
self.entity = entity
nd.showBoundingBox = True
self.animationStates.append(entity.getAnimationState('Walk'))
self.animationStates[-1].enabled = True
self.animationSpeeds.append(ogre.Math.RangeRandom(0.5, 1.5))
light = sceneManager.createLight('BlueLight')
light.position = (-200, -80, -100)
light.diffuseColour = (0.5, 0.5, 1.0)
light.position=(9, 0, 0)
light = sceneManager.createLight('GreenLight')
light.position = (0, 0, -100)
light.diffuseColour = (0.5, 1.0, 0.5)
camera.position = (100, 50, 100)
camera.lookAt(-50, 50, 0)
entity.addSoftwareAnimationRequest(False)
# Report whether hardware skinning is enabled or not
subEntity = entity.getSubEntity(0)
material = subEntity.material
technique = material.bestTechnique
techniquePass = technique.getPass(0)
if techniquePass.hasVertexProgram and techniquePass.vertexProgram.skeletalAnimationIncluded:
self.renderWindow.debugText = 'Hardware skinning is enabled'
else:
self.renderWindow.debugText = 'Software skinning is enabled'
# use this for our pseudo bounding box, to use manual object instead
self.boundEntity = sceneManager.createEntity("cube", "cube.mesh")
boxNode = sceneManager.rootSceneNode.createChildSceneNode()
boxNode.attachObject(self.boundEntity)
boxNode.showBoundingBox = True
boxNode.scale = (0.1,0.1,0.1)
self.boundEntity.addSoftwareAnimationRequest(False)
def _createFrameListener(self):
self.frameListener = SkeletalAnimationFrameListener(self.renderWindow, self.camera, self.animationStates, self.animationSpeeds,self.entity, self.boundEntity)
self.root.addFrameListener(self.frameListener)
class SkeletalAnimationFrameListener(sf.FrameListener):
def __init__(self, renderWindow, camera, animationStates, animationSpeeds,entity, boundEntity):
sf.FrameListener.__init__(self, renderWindow, camera)
self.animationStates = animationStates
self.animationSpeeds = animationSpeeds
self.robotEntity = entity
self.boxEntity = boundEntity
self.robotNode = self.robotEntity.parentSceneNode
self.boxNode = self.boxEntity.parentSceneNode
self.boxExtents = Extents(self.boxEntity)
def frameStarted(self, frameEvent):
for index in xrange(0,len(self.animationStates)):
self.animationStates[index].addTime(frameEvent.timeSinceLastFrame * self.animationSpeeds[index])
extents = Extents(self.robotEntity)
self.boxNode.position = self.robotEntity.boundingBox.center
emx = extents[1][0] - extents[0][0]
emy = extents[1][1] - extents[0][1]
emz = extents[1][2] - extents[0][2]
bmx = self.boxExtents[1][0] - self.boxExtents[0][0]
bmy = self.boxExtents[1][1] - self.boxExtents[0][1]
bmz = self.boxExtents[1][2] - self.boxExtents[0][2]
if emx < bmx:
sx = emx / bmx
else:
sx = bmx / emx
if emy < bmy:
sy = emy / bmy
else:
sy = bmy / emy
if emz < bmz:
sz = emz / bmz
else:
sz = bmz / emz
self.boxNode.scale = ( sx, sy, sz)
return sf.FrameListener.frameStarted(self, frameEvent)
def Extents(entity):
min_x, min_y, min_z = 999999, 999999, 999999
max_x, max_y, max_z = -999999, -999999, -999999
for s in range(entity.numSubEntities):
vertices = entity.getSubEntityVertices(s)
#print len(vertices)
for v in vertices:
if v[0] < min_x:
min_x = v[0]
if v[1] < min_y:
min_y = v[1]
if v[2] < min_z:
min_z = v[2]
if v[0] > max_x:
max_x = v[0]
if v[1] > max_y:
max_y = v[1]
if v[2] > max_z:
max_z = v[2]
del vertices
return (min_x, min_y, min_z), (max_x, max_y, max_z)
if __name__ == '__main__':
try:
application = SkeletalApplication()
application.go()
except ogre.OgreException, e:
print e
Note if the entities' mesh use sharedVertexData you only need to return the first e.g., pseudocode
if entity.mesh.sharedVertexData:
vertices = entity.getSubEntityVertices(0)
......
else:
for s in range(entity.numSubEntities):
vertices = entity.getSubEntityVertices(s)
......
nathan75
07-11-2006 08:58:47
My mesh is control by ODE, so get sub entity can not help me.
However I did not use OgreOde. I mapped the ode body to ogre bone by myself.
I just want to set a bigger bounding box when starting or display the mesh any time no matter if it in the window of the camera.
Is there any switch to turn off the effect of bounding box?
BTW, I tried to run you example, I saw that the mesh of robot have so big a bounding box, far more bigger than the mesh itself, how can you do that? If I could make so big a boundingbox, my problem will be solved.
Thank you very much!
dermont
07-11-2006 09:37:36
By setting the boundsPaddingFactor (0 to 1.0, default 0.01) and preloading the mesh, see the first reply.
ogre.MeshManager.getSingleton().boundsPaddingFactor = 0.80
mesh = ogre.MeshManager.getSingleton().load("ogrehead.mesh", 'General')
entity = sceneManager.createEntity("Head", 'ogrehead.mesh')
headNode = sceneManager.rootSceneNode.createChildSceneNode((10, -50, -100))
headNode.attachObject(entity)
headNode.showBoundingBox = True