View Single Post
  #6  
Old 03-03-2008, 05:27 PM
farshizzo farshizzo is offline
WorldViz Team Member
 
Join Date: Mar 2003
Posts: 2,849
Here is a script that creates an action that is similar to vizact.goto() except the speed is in pixels/sec. Run the script and press space bar to run the action.
Code:
import viz
viz.go()

class MovePixelSpeedAction(viz.ActionClass):
	
	def convertToPixels(self,pos):
		screen = self.window.worldToScreen(pos)
		screen[0] *= self.size[0]
		screen[1] *= self.size[1]
		screen[2] = 0.0
		return screen
	
	def intersectLine(self,line1,line2):
		o1 = viz.Vector(line1.getBegin())
		o2 = viz.Vector(line2.getBegin())
		d1 = viz.Vector(line1.getDir(),normalize=True)
		d2 = viz.Vector(line2.getDir(),normalize=True)
		c = d1 ^ d2
		clen = c.length()
		if clen == 0.0:
			return o1
		
		#Compute determinant
		v = o2 - o1
		d = (v[0] * (d2[1]*c[2] - d2[2]*c[1])) - (v[1] * (d2[0]*c[2]-d2[2]*c[0])) + (v[2] * (d2[0]*c[1]-d2[1]*c[0]))
		
		d1.setLength(d / (clen * clen))
		return o1 + d1
	
	def begin(self,object):

		self.window = viz.MainWindow
		self.size = self.window.getSize(viz.WINDOW_PIXELS)

		#Get begin/end positions
		beginVal = object.getPosition()
		endVal = vizact._paramlist_(self._actiondata_.pos,object)
		
		#Convert to pixel coordinates
		beginScreenVal = self.convertToPixels(beginVal)
		endScreenVal = self.convertToPixels(endVal)
		
		#Compute distance to travel
		dist = vizmat.Distance(beginScreenVal,endScreenVal)
		if dist == 0.0:
			self.end(object)
			return
			
		#Get velocity
		vel = vizact._paramval_(self._actiondata_.vel,object)
		
		#Calculate duration
		self.duration = dist / vel
		
		#Initialize variables
		self.elapsed = 0.0
		self.endVal = endVal
		self.beginScreenVal = beginScreenVal
		self.endScreenVal = endScreenVal
		self.worldLine = viz.Line(begin=beginVal,end=endVal)
		
	def update(self,elapsed,object):
		
		self.elapsed += elapsed
		p = self.elapsed / self.duration
		if p >= 1.0:
			self._overtime_ = self.elapsed - self.duration
			object.translate(self.endVal)
			self.end(object)
			return
			
		#Interpolate screen pos from screen velocity
		screenPos = vizmat.Interpolate(self.beginScreenVal,self.endScreenVal,p)
	
		#Convert screen location to world vector
		line = self.window.screenToWorld( [screenPos[0]/self.size[0],screenPos[1]/self.size[1]] )
		
		#Intersect vector with world vector of movement path
		pos = self.intersectLine(self.worldLine,line)
		object.translate(pos)
		
def movePixelSpeed(pos,vel):
	bla = viz.ActionData()
	bla.pos = pos
	bla.vel = vel
	bla.actionclass = MovePixelSpeedAction
	return bla
	
START_POS = (0,0,8)
STOP_POS = (0,4,30)

ball = viz.add('ball.wrl',pos=START_POS)

def RunAction():
	ball.translate(START_POS)
	ball.runAction(movePixelSpeed(STOP_POS,100))
	
vizact.onkeydown(' ',RunAction)
Reply With Quote