How does entity.boundingBox.setExtents work?

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:02:11

See this thread:
http://www.ogre3d.org/phpBB2/viewtopic. ... unding+box

e.g.

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')


http://www.ogre3d.org/docs/api/html/cla ... nager.html

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