blz
10-11-2011 21:52:20
Hello,
I've been attempting to extend the code from Intermediate Tutorial 1 such that I can animate the translation of an arbitrary number of entities. In order to do this, I have created an animableEntity class in which all animation-related data is placed. This includes a pointer to the SceneNode and entity objects (see code below).
I have three distinct problems which I will outline below. I have also attempted to whittle my code down to a manageable testcase -- please note that this code (like all tutorial code) relies on the sample framework.
Problem 1: Entity overshoots destination and moves off screen
Problem Description: If you run the code provided at the bottom of this post, you should see two non-animated robots and a single animated one. The non-animated robots are simply references. The one on the left marks the starting position for the animated entity and the one on the right marks the prescribed destination. Instead of walking in a straight line towards the robot on the right, the animated robot walks through his destination and off the screen, only to suddenly reappear at his destination 30 seconds to a minute later.
I am reusing the code from Intermediate Tutorial I which places the entity at its prescribed destination if the distance to said destination is <= 0.0. I suspect this is not the problem, since I have not touched these particular lines, but here they are just in case I missed something:
Problem 2: Entity translation speed is correlated with distance to destination
This is also quite strange. I noticed that my animated robot will move faster if the waypoint is placed farther away. I can't even begin to understand what could be the cause of this! Again, the code above has not been significantly modified from the Intermediate Tutorial I code. Any suggestions?
Problem 3: Entities cannot be scaled by calling entity.scale
This should be fairly self-explanatory. I call startEnt.scale = (.1, .1, .1) at lines 134 and 139, but the two nonanimated robots are as large as the animated one! Any ideas what may be the cause?
Complete Testcase (apologies for the length, but I don't know how to make it any shorter!)
I realize this post is a fairly open-ended cry for debugging help, but I've looked at this for several days and I really don't know where to go from here.
Any sort of help would be immensely appreciated!
Thank you in advance!
- blz
I've been attempting to extend the code from Intermediate Tutorial 1 such that I can animate the translation of an arbitrary number of entities. In order to do this, I have created an animableEntity class in which all animation-related data is placed. This includes a pointer to the SceneNode and entity objects (see code below).
I have three distinct problems which I will outline below. I have also attempted to whittle my code down to a manageable testcase -- please note that this code (like all tutorial code) relies on the sample framework.
Problem 1: Entity overshoots destination and moves off screen
Problem Description: If you run the code provided at the bottom of this post, you should see two non-animated robots and a single animated one. The non-animated robots are simply references. The one on the left marks the starting position for the animated entity and the one on the right marks the prescribed destination. Instead of walking in a straight line towards the robot on the right, the animated robot walks through his destination and off the screen, only to suddenly reappear at his destination 30 seconds to a minute later.
I am reusing the code from Intermediate Tutorial I which places the entity at its prescribed destination if the distance to said destination is <= 0.0. I suspect this is not the problem, since I have not touched these particular lines, but here they are just in case I missed something:
move = self.walkSpeed * self.ev_evt.timeSinceLastFrame
self.distance -= move
if self.distance <= 0.0: # if unit has overshot destination, place on destination
self.node.setPosition(self.destination)
if not self.nextLocation(): # if no waypoints remaining
self.stopWalking()
else:
self.node.translate(self.destination * move)
Problem 2: Entity translation speed is correlated with distance to destination
This is also quite strange. I noticed that my animated robot will move faster if the waypoint is placed farther away. I can't even begin to understand what could be the cause of this! Again, the code above has not been significantly modified from the Intermediate Tutorial I code. Any suggestions?
Problem 3: Entities cannot be scaled by calling entity.scale
This should be fairly self-explanatory. I call startEnt.scale = (.1, .1, .1) at lines 134 and 139, but the two nonanimated robots are as large as the animated one! Any ideas what may be the cause?
Complete Testcase (apologies for the length, but I don't know how to make it any shorter!)
import ogre.renderer.OGRE as ogre
import SampleFramework as sf
import ogre.gui.CEGUI as CEGUI
import ogre.io.OIS as OIS
class animableEntity:
def __init__(self, entity, node):
# Identity
self.entity = entity
self.entity
self.node = node
# Movement
self.wayPoints = []
#self.walkSpeed = 35.0
self.walkSpeed = 1
self.destination = None
self.direction = ogre.Vector3().ZERO
self.distance = 0.0 # dist left to travel
self.walking = False
# Animation
self.ev_evt = None # contains timeSinceLastFrame
self.animationState = self.entity.getAnimationState('Idle')
self.animationState.setLoop(True)
self.animationState.setEnabled(True)
def go(self, evt):
'''Calls all relevant functions for a single unit: movement, shooting, etc...'''
self.ev_evt = evt
self.walk()
self.animationState.addTime(self.ev_evt.timeSinceLastFrame)
def walk(self):
if not self.walking:
if len(self.wayPoints):
self.startWalking() ## if you're not already walking AND there are waypoints, start walking
else:
self.step()
def addWaypoint(self, coords_Vector3):
'''Takes in ogre.Vector3'''
self.wayPoints.append(coords_Vector3)
def startWalking(self):
if self.nextLocation():
self.animationState = self.entity.getAnimationState('Walk')
self.animationState.setLoop(True)
self.animationState.setEnabled(True)
self.walking = True
def stopWalking(self):
self.animationState = self.entity.getAnimationState('Idle')
self.animationState.setLoop(True)
self.animationState.setEnabled(True)
self.walking = False
def nextLocation(self):
'''
Prepares translation-related member variables for next waypoint.
Must be run prior to moving to waypoint.
Returns ogre.Vector3 with coords to next waypoint.
'''
if len(self.wayPoints) == 0:
return False
self.destination = self.wayPoints.pop(0) # FIFO behavior
self.direction = self.destination - self.node.getPosition()
self.distance = self.direction.normalise()
self.handleTurns()
return True
def handleTurns(self):
src = self.node.getOrientation() * ogre.Vector3().UNIT_X
if 1.0 + src.dotProduct(self.direction) < 0.0001:
self.node.yaw(ogre.Degree(180))
else:
quat = src.getRotationTo(self.direction)
self.node.rotate(quat)
def step(self):
move = self.walkSpeed * self.ev_evt.timeSinceLastFrame
self.distance -= move
if self.distance <= 0.0: # if unit has overshot destination, place on destination
self.node.setPosition(self.destination)
if not self.nextLocation(): # if no waypoints remaining
self.stopWalking()
else:
self.node.translate(self.destination * move)
class EventListener(sf.FrameListener):
'''Handles input, update model and perform checks before rendering'''
def __init__(self, win, cam, sc, ent, node):
## Subclass any Python-Ogre class and you *must* call its constructor
sf.FrameListener.__init__(self, win, cam, True, True)
## Initialize Class Variables
self.moveSpeed = 50
self.rotateSpeed = 1/500.0
self.sceneManager = sc
self.camera = cam
self.aEnt = []
## Testcase Varaibles
self.aEntInit = False
self.ent = ent
self.node = node
def frameStarted(self, evt):
# Process samepleframework frame listener. Needs to happen first, as we will manipulate the translate vector.
if not sf.FrameListener.frameStarted(self, evt):
return False
if not self.aEntInit:
self.aEnt.append(animableEntity(self.ent, self.node))
self.aEnt[0].addWaypoint(ogre.Vector3(400,0,0)) ## Waypoint
self.aEntInit = True
## Unit animation and transform
for unit in self.aEnt:
unit.go(evt) # process unit
# print unit.node.getPosition() ## DEBUG
# print "\n" ## END DEBUG
return True
class TutorialApplication(sf.Application):
'''Application Class'''
def _createScene(self):
self.ent = self.sceneManager.createEntity('Robot','robot.mesh')
location = ogre.Vector3().ZERO
self.node = self.sceneManager.getRootSceneNode().createChildSceneNode('RobotNode', location)
self.node.attachObject(self.ent)
startEnt = self.sceneManager.createEntity('startRobot', 'robot.mesh')
startEnt.scale = (.1, .1, .1)
startNode = self.sceneManager.getRootSceneNode().createChildSceneNode('StartNode', location)
startNode.attachObject(startEnt)
refEnt = self.sceneManager.createEntity('refRobot', 'robot.mesh')
refEnt.scale = (.01, .01, .01)
refNode = self.sceneManager.getRootSceneNode().createChildSceneNode('refNode', ogre.Vector3(400,0,0))
refNode.attachObject(refEnt)
def _createCamera(self):
self.camera = self.sceneManager.createCamera('PlayerCam')
self.camera.setPosition(600, 1000, 1000)
self.camera.lookAt(ogre.Vector3(600,0,0))
self.camera.nearClipDistance = 5
def _createFrameListener(self):
self.frameListener = EventListener(self.renderWindow,
self.camera,
self.sceneManager,
self.ent,
self.node
)
self.root.addFrameListener(self.frameListener)
self.frameListener.showDebugOverlay(True)
if __name__ == '__main__':
ta = TutorialApplication()
ta.go()
I realize this post is a fairly open-ended cry for debugging help, but I've looked at this for several days and I really don't know where to go from here.

Thank you in advance!
- blz