PDA

View Full Version : how to bind text to objects


burt01041
08-13-2008, 10:34 AM
i have a question, you know how in the tutorials it shows how to bind the mona lisa video to the screen? how would i do this with text... so that if also the player press a button, the screen would go up, and the text along with it.
any suggestions...?

farshizzo
08-13-2008, 02:00 PM
You will need to manually scale and position the text so that it lies on the screen surface. You will probably need to use the zoffset command also, to prevent z-fighting artifacts.

burt01041
08-14-2008, 08:18 AM
i don't understand too well, what you mean by this... is there a tutorial on such thing?
thanks btw

farshizzo
08-14-2008, 04:57 PM
There is no tutorial that directly addresses this issue. You just need to use the standard node.setPosition/setEuler/setScale functions to place the text where you want it to show up, in this case on top of the screen.

John P
08-14-2008, 07:00 PM
I have some code that you can feel free to use. It might be overkill but it should do the job.

It uses an action to build a billboard like behavior. eg. the billboard node looks directly at the camera position rather than matching the camera alignment. It was useful in a cave scenario. It also deals with Z order and depth write to ensure the text is visible.

Otherwise you just call AttachSpeechBubble to float some text above an object.

import viz

viz.go()

#########Utility Class and Functions for Speech Bubble############
# all you need to call is AttachSpeechBubble
#code is based upon worldviz avatar lookat tutorial
MAXLINELENGTH = 60
class BillboardToNodeAction(viz.ActionClass):
def begin(self,object):
"""Called once when action starts"""
self.nodeToLookAt = self._actiondata_.data[0]
self.nodeToModify = self._actiondata_.data[1]
self.duration = self._actiondata_.data[2]
self.blendIn = self._actiondata_.data[3]
self.timeElapsed = 0
self.startQuat = self.nodeToModify.getQuat()
def update(self,elapsed,object):
self.timeElapsed += elapsed
p = 1
if self.blendIn <> 0.0:
p = self.timeElapsed / self.blendIn

positionToLookAt = self.nodeToLookAt.getPosition()
for ix in range(3):
positionToLookAt[ix] = self.nodeToModify.getPosition()[ix] + self.nodeToModify.getPosition()[ix] - positionToLookAt[ix]
if self.duration > 0.0 and self.timeElapsed > self.duration:
self.nodeToModify.lookat(positionToLookAt, 0, viz.ABS_GLOBAL)
self.end(object)
elif p < 1.0:
self.nodeToModify.lookat( positionToLookAt, 0, viz.ABS_GLOBAL )
targetQuat = self.nodeToModify.getQuat()
nextQuad = vizmat.slerp(self.startQuat,targetQuat,p)
self.nodeToModify.setQuat(nextQuad)
else:
self.nodeToModify.lookat(positionToLookAt, 0, viz.ABS_GLOBAL)
def end(self,object):
viz.ActionClass.end(self,object)

#Function to construct the action instance
def billboardNode( nodeToLookAt, nodeToModify, duration = viz.FOREVER, blendIn = 0.0):
action = viz.ActionData()
action.data = [ nodeToLookAt, nodeToModify, duration, blendIn ]
action.actionclass = BillboardToNodeAction
return action

def FormatTextbox(msg):
length = len(msg)

lastspace = 0
while lastspace + MAXLINELENGTH < length and lastspace <> -1:
lastspace = msg.rfind(' ',lastspace, lastspace + MAXLINELENGTH)
if lastspace > 0 and lastspace < length:
msg = msg[:lastspace] + '\n' + msg[lastspace+1:]
else:
lastspace = -1

lines = msg.splitlines()

return lines

def AttachSpeechBubble(dest,message, height = 1.8):

lines = FormatTextbox(message)

rootline = 0
parentline = 0
for lineix in range(len(lines),0,-1):
speechline = viz.addText(lines[lineix-1])
speechline.alignment(viz.TEXT_CENTER_BOTTOM)
if not rootline:
rootline = speechline
parentline = speechline
else:
speechline.parent(parentline)
parentline = speechline
speechline.translate([0,1.0,0])
speechline.draworder(13)
speechline.depthFunc(viz.GL_ALWAYS)
speechline.disable(viz.DEPTH_WRITE)

speechtext = rootline

speechbox = speechtext.getBoundingBox()
speechtext.setScale([0.12,0.12,0.12])

viz.startlayer(viz.QUADS)
viz.vertex(speechbox.xmin-0.1,speechbox.ymax+0.1,0)
viz.vertex(speechbox.xmax+0.1,speechbox.ymax+0.1,0 )
viz.vertex(speechbox.xmax+0.1,speechbox.ymin-0.1,0)
viz.vertex(speechbox.xmin-0.1,speechbox.ymin-0.1,0)
speechquad = viz.endlayer()
speechquad.color([0,0,0])
speechquad.disable(viz.CULL_FACE)
speechquad.parent(speechtext)
speechquad.draworder(12)
speechquad.alpha(0.5)
speechquad.depthFunc(viz.GL_ALWAYS)
speechquad.disable(viz.DEPTH_WRITE)

if type(dest) == list:
speechtext.translate(dest)
else:
linkposition = viz.link(dest, speechtext)
linkposition.setMask(viz.LINK_POS)
linkposition.preTrans([0, height, 0])

speechtext.addAction(billboardNode(viz.MainView,sp eechtext))

return speechtext
#################################

viz.clearcolor(0,0,0.5)
box = viz.add("box.wrl")
box.setPosition(0,2,7)

AttachSpeechBubble(dest = box,message = "This text floats above the box",height = 1.0)

burt01041
08-18-2008, 10:16 AM
what is this 'AttachSpeechBubble' you speak of? will it allow an avatar to have a floating text bubble if an event is triggered?