Advertisement
Guest User

Untitled

a guest
Jun 25th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.94 KB | None | 0 0
  1. from direct.directnotify.DirectNotifyGlobal import directNotify
  2. from direct.showbase import DirectObject
  3. from direct.controls.ControlManager import CollisionHandlerRayStart
  4. from direct.showbase.InputStateGlobal import inputState
  5. from direct.task.Task import Task
  6. from pandac.PandaModules import *
  7. import math
  8.  
  9.  
  10. class GravityWalker(DirectObject.DirectObject):
  11. notify = directNotify.newCategory("GravityWalker")
  12. wantDebugIndicator = 1# base.config.GetBool('want-avatar-physics-indicator', 0)
  13. wantFloorSphere = 0 #base.config.GetBool('want-floor-sphere', 0)
  14. earlyEventSphere = 0 #base.config.GetBool('early-event-sphere', 0)
  15.  
  16. DiagonalFactor = math.sqrt(2.) / 2.
  17.  
  18. # special methods
  19. def __init__(self, gravity = 64.348, standableGround=0.707,
  20. hardLandingForce=16.0, legacyLifter=False):
  21. assert self.notify.debugStateCall(self)
  22. DirectObject.DirectObject.__init__(self)
  23. self.__gravity=gravity
  24. self.__standableGround=standableGround
  25. self.__hardLandingForce=hardLandingForce
  26. self._legacyLifter = legacyLifter
  27.  
  28. self.mayJump = 1
  29. self.jumpDelayTask = None
  30.  
  31. self.controlsTask = None
  32. self.indicatorTask = None
  33.  
  34. self.falling = 0
  35. self.needToDeltaPos = 0
  36. self.physVelocityIndicator=None
  37. self.avatarControlForwardSpeed=0
  38. self.avatarControlJumpForce=0
  39. self.avatarControlReverseSpeed=0
  40. self.avatarControlRotateSpeed=0
  41. self.getAirborneHeight=None
  42.  
  43. self.priorParent=Vec3(0)
  44. self.__oldPosDelta=Vec3(0)
  45. self.__oldDt=0
  46.  
  47. self.moving=0
  48. self.speed=0.0
  49. self.rotationSpeed=0.0
  50. self.slideSpeed=0.0
  51. self.vel=Vec3(0.0)
  52. self.collisionsActive = 0
  53.  
  54. self.isAirborne = 0
  55. self.highMark = 0
  56.  
  57. """
  58. def spawnTest(self):
  59. assert self.notify.debugStateCall(self)
  60. if not self.wantDebugIndicator:
  61. return
  62. from pandac.PandaModules import *
  63. from direct.interval.IntervalGlobal import *
  64. from toontown.coghq import MovingPlatform
  65.  
  66. if hasattr(self, "platform"):
  67. # Remove the prior instantiation:
  68. self.moveIval.pause()
  69. del self.moveIval
  70. self.platform.destroy()
  71. del self.platform
  72. self.platform2.destroy()
  73. del self.platform2
  74.  
  75. model = loader.loadModel('phase_9/models/cogHQ/platform1')
  76. fakeId = id(self)
  77. self.platform = MovingPlatform.MovingPlatform()
  78. self.platform.setupCopyModel(fakeId, model, 'platformcollision')
  79. self.platformRoot = render.attachNewNode("GravityWalker-spawnTest-%s"%fakeId)
  80. self.platformRoot.setPos(base.localAvatar, Vec3(0.0, 0.0, 1.0))
  81. self.platformRoot.setHpr(base.localAvatar, Vec3.zero())
  82. self.platform.reparentTo(self.platformRoot)
  83.  
  84. self.platform2 = MovingPlatform.MovingPlatform()
  85. self.platform2.setupCopyModel(1+fakeId, model, 'platformcollision')
  86. self.platform2Root = render.attachNewNode("GravityWalker-spawnTest2-%s"%fakeId)
  87. self.platform2Root.setPos(base.localAvatar, Vec3(-16.0, 30.0, 1.0))
  88. self.platform2Root.setHpr(base.localAvatar, Vec3.zero())
  89. self.platform2.reparentTo(self.platform2Root)
  90.  
  91. duration = 5
  92. self.moveIval = Parallel(
  93. Sequence(
  94. WaitInterval(0.3),
  95. LerpPosInterval(self.platform, duration,
  96. Vec3(0.0, 30.0, 0.0),
  97. name='platformOut%s' % fakeId,
  98. fluid = 1),
  99. WaitInterval(0.3),
  100. LerpPosInterval(self.platform, duration,
  101. Vec3(0.0, 0.0, 0.0),
  102. name='platformBack%s' % fakeId,
  103. fluid = 1),
  104. WaitInterval(0.3),
  105. LerpPosInterval(self.platform, duration,
  106. Vec3(0.0, 0.0, 30.0),
  107. name='platformUp%s' % fakeId,
  108. fluid = 1),
  109. WaitInterval(0.3),
  110. LerpPosInterval(self.platform, duration,
  111. Vec3(0.0, 0.0, 0.0),
  112. name='platformDown%s' % fakeId,
  113. fluid = 1),
  114. ),
  115. Sequence(
  116. WaitInterval(0.3),
  117. LerpPosInterval(self.platform2, duration,
  118. Vec3(0.0, -30.0, 0.0),
  119. name='platform2Out%s' % fakeId,
  120. fluid = 1),
  121. WaitInterval(0.3),
  122. LerpPosInterval(self.platform2, duration,
  123. Vec3(0.0, 30.0, 30.0),
  124. name='platform2Back%s' % fakeId,
  125. fluid = 1),
  126. WaitInterval(0.3),
  127. LerpPosInterval(self.platform2, duration,
  128. Vec3(0.0, -30.0, 0.0),
  129. name='platform2Up%s' % fakeId,
  130. fluid = 1),
  131. WaitInterval(0.3),
  132. LerpPosInterval(self.platform2, duration,
  133. Vec3(0.0, 0.0, 0.0),
  134. name='platformDown%s' % fakeId,
  135. fluid = 1),
  136. ),
  137. name='platformIval%s' % fakeId,
  138. )
  139. self.moveIval.loop()
  140. """
  141. def setWalkSpeed(self, forward, jump, reverse, rotate):
  142. assert self.notify.debugStateCall(self)
  143. self.avatarControlForwardSpeed=forward
  144. self.avatarControlJumpForce=jump
  145. self.avatarControlReverseSpeed=reverse
  146. self.avatarControlRotateSpeed=rotate
  147.  
  148. def getSpeeds(self):
  149. #assert self.debugPrint("getSpeeds()")
  150. return (self.speed, self.rotationSpeed, self.slideSpeed)
  151.  
  152. def getIsAirborne(self):
  153. return self.isAirborne
  154.  
  155. def setAvatar(self, avatar):
  156. self.avatar = avatar
  157. if avatar is not None:
  158. pass # setup the avatar
  159.  
  160. def setupRay(self, bitmask, floorOffset, reach):
  161. assert self.notify.debugStateCall(self)
  162. # This is a ray cast from your head down to detect floor polygons.
  163. # This ray start is arbitrarily high in the air. Feel free to use
  164. # a higher or lower value depending on whether you want an avatar
  165. # that is outside of the world to step up to the floor when they
  166. # get under valid floor:
  167. cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0)
  168. cRayNode = CollisionNode('GW.cRayNode')
  169. cRayNode.addSolid(cRay)
  170. self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode)
  171. cRayNode.setFromCollideMask(bitmask)
  172. cRayNode.setIntoCollideMask(BitMask32.allOff())
  173.  
  174. # set up floor collision mechanism
  175. self.lifter = CollisionHandlerGravity()
  176. #self.lifter = CollisionHandlerHighestEvent()
  177. self.lifter.setLegacyMode(self._legacyLifter)
  178. self.lifter.setGravity(self.__gravity)
  179. self.lifter.addInPattern("enter%in")
  180. self.lifter.addAgainPattern("again%in")
  181. self.lifter.addOutPattern("exit%in")
  182. self.lifter.setOffset(floorOffset)
  183. self.lifter.setReach(reach)
  184.  
  185. # Limit our rate-of-fall with the lifter.
  186. # If this is too low, we actually "fall" off steep stairs
  187. # and float above them as we go down. I increased this
  188. # from 8.0 to 16.0 to prevent this
  189. #self.lifter.setMaxVelocity(16.0)
  190.  
  191. self.lifter.addCollider(self.cRayNodePath, self.avatarNodePath)
  192.  
  193. def setupWallSphere(self, bitmask, avatarRadius):
  194. """
  195. Set up the collision sphere
  196. """
  197. assert self.notify.debugStateCall(self)
  198. # This is a sphere on the ground to detect collisions with
  199. # walls, but not the floor.
  200. self.avatarRadius = avatarRadius
  201. cSphere = CollisionSphere(0.0, 0.0, avatarRadius, avatarRadius)
  202. cSphereNode = CollisionNode('GW.cWallSphereNode')
  203. cSphereNode.addSolid(cSphere)
  204. cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
  205.  
  206. cSphereNode.setFromCollideMask(bitmask)
  207. cSphereNode.setIntoCollideMask(BitMask32.allOff())
  208.  
  209. # set up collision mechanism
  210. if config.GetBool('want-fluid-pusher', 0):
  211. self.pusher = CollisionHandlerFluidPusher()
  212. else:
  213. self.pusher = CollisionHandlerPusher()
  214. self.pusher.addCollider(cSphereNodePath, self.avatarNodePath)
  215. self.cWallSphereNodePath = cSphereNodePath
  216.  
  217. def setupEventSphere(self, bitmask, avatarRadius):
  218. """
  219. Set up the collision sphere
  220. """
  221. assert self.notify.debugStateCall(self)
  222. # This is a sphere a little larger than the wall sphere to
  223. # trigger events.
  224. self.avatarRadius = avatarRadius
  225. cSphere = CollisionSphere(0.0, 0.0, avatarRadius-0.1, avatarRadius*1.04)
  226. # Mark it intangible just to emphasize its non-physical purpose.
  227. cSphere.setTangible(0)
  228. cSphereNode = CollisionNode('GW.cEventSphereNode')
  229. cSphereNode.addSolid(cSphere)
  230. cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
  231.  
  232. cSphereNode.setFromCollideMask(bitmask)
  233. cSphereNode.setIntoCollideMask(BitMask32.allOff())
  234.  
  235. # set up collision mechanism
  236. self.event = CollisionHandlerEvent()
  237. self.event.addInPattern("enter%in")
  238. self.event.addOutPattern("exit%in")
  239. self.cEventSphereNodePath = cSphereNodePath
  240.  
  241. def setupFloorSphere(self, bitmask, avatarRadius):
  242. """
  243. Set up the collision sphere
  244. """
  245. assert self.notify.debugStateCall(self)
  246. # This is a tiny sphere concentric with the wallSphere to keep
  247. # us from slipping through floors.
  248. self.avatarRadius = avatarRadius
  249. cSphere = CollisionSphere(0.0, 0.0, avatarRadius, 0.01)
  250. cSphereNode = CollisionNode('GW.cFloorSphereNode')
  251. cSphereNode.addSolid(cSphere)
  252. cSphereNodePath = self.avatarNodePath.attachNewNode(cSphereNode)
  253.  
  254. cSphereNode.setFromCollideMask(bitmask)
  255. cSphereNode.setIntoCollideMask(BitMask32.allOff())
  256.  
  257. # set up collision mechanism
  258. self.pusherFloorhandler = CollisionHandlerPusher()
  259. self.pusherFloor.addCollider(cSphereNodePath, self.avatarNodePath)
  260. self.cFloorSphereNodePath = cSphereNodePath
  261.  
  262. def setWallBitMask(self, bitMask):
  263. self.wallBitmask = bitMask
  264.  
  265. def setFloorBitMask(self, bitMask):
  266. self.floorBitmask = bitMask
  267.  
  268. def swapFloorBitMask(self, oldMask, newMask):
  269. self.floorBitmask = self.floorBitmask &~ oldMask
  270. self.floorBitmask |= newMask
  271.  
  272. if self.cRayNodePath and not self.cRayNodePath.isEmpty():
  273. self.cRayNodePath.node().setFromCollideMask(self.floorBitmask)
  274.  
  275. def setGravity(self, gravity):
  276. self.__gravity = gravity
  277. self.lifter.setGravity(self.__gravity)
  278.  
  279. def getGravity(self, gravity):
  280. return self.__gravity
  281.  
  282. def initializeCollisions(self, collisionTraverser, avatarNodePath,
  283. avatarRadius = 1.4, floorOffset = 1.0, reach = 1.0):
  284. """
  285. floorOffset is how high the avatar can reach. I.e. if the avatar
  286. walks under a ledge that is <= floorOffset above the ground (a
  287. double floor situation), the avatar will step up on to the
  288. ledge (instantly).
  289.  
  290. Set up the avatar collisions
  291. """
  292. assert self.notify.debugStateCall(self)
  293.  
  294. assert not avatarNodePath.isEmpty()
  295. self.avatarNodePath = avatarNodePath
  296.  
  297. self.cTrav = collisionTraverser
  298.  
  299. self.setupRay(self.floorBitmask, floorOffset, reach)
  300. self.setupWallSphere(self.wallBitmask, avatarRadius)
  301. self.setupEventSphere(self.wallBitmask, avatarRadius)
  302. if self.wantFloorSphere:
  303. self.setupFloorSphere(self.floorBitmask, avatarRadius)
  304.  
  305. self.setCollisionsActive(1)
  306.  
  307. def setTag(self, key, value):
  308. self.cEventSphereNodePath.setTag(key, value)
  309.  
  310. def setAirborneHeightFunc(self, unused_parameter):
  311. assert self.notify.debugStateCall(self)
  312. self.getAirborneHeight = self.lifter.getAirborneHeight
  313.  
  314. def getAirborneHeight(self):
  315. assert self.notify.debugStateCall(self)
  316. self.lifter.getAirborneHeight()
  317.  
  318. def setAvatarPhysicsIndicator(self, indicator):
  319. """
  320. indicator is a NodePath
  321. """
  322. assert self.notify.debugStateCall(self)
  323. self.cWallSphereNodePath.show()
  324.  
  325. def deleteCollisions(self):
  326. assert self.notify.debugStateCall(self)
  327. del self.cTrav
  328.  
  329. self.cWallSphereNodePath.removeNode()
  330. del self.cWallSphereNodePath
  331. if self.wantFloorSphere:
  332. self.cFloorSphereNodePath.removeNode()
  333. del self.cFloorSphereNodePath
  334.  
  335. del self.pusher
  336. # del self.pusherFloor
  337. del self.event
  338. del self.lifter
  339.  
  340. del self.getAirborneHeight
  341.  
  342. def setCollisionsActive(self, active = 1):
  343. assert self.notify.debugStateCall(self)
  344. if self.collisionsActive != active:
  345. self.collisionsActive = active
  346. # Each time we change the collision geometry, make one
  347. # more pass to ensure we aren't standing in a wall.
  348. self.oneTimeCollide()
  349. # make sure we have a shadow traverser
  350. base.initShadowTrav()
  351. if active:
  352. if 1:
  353. # Please let skyler or drose know if this is causing a problem
  354. # This is a bit of a hack fix:
  355. self.avatarNodePath.setP(0.0)
  356. self.avatarNodePath.setR(0.0)
  357. self.cTrav.addCollider(self.cWallSphereNodePath, self.pusher)
  358. if self.wantFloorSphere:
  359. self.cTrav.addCollider(self.cFloorSphereNodePath, self.pusherFloor)
  360. # Add the lifter to the shadow traverser, which runs after
  361. # our traverser. This prevents the "fall through wall and
  362. # off ledge" bug. The problem was that we couldn't control
  363. # which collided first, the wall pusher or the lifter, if
  364. # they're in the same collision traverser. If the lifter
  365. # collided first, we'd start falling before getting pushed
  366. # back behind the wall.
  367. base.shadowTrav.addCollider(self.cRayNodePath, self.lifter)
  368.  
  369. if self.earlyEventSphere:
  370. # If we want to trigger the events at the same
  371. # time as we intersect walls (e.g. Toontown, for
  372. # backward compatibility issues), add the event
  373. # sphere to the main traverser. This allows us to
  374. # hit door triggers that are just slightly behind
  375. # the door itself.
  376. self.cTrav.addCollider(self.cEventSphereNodePath, self.event)
  377. else:
  378. # Normally, we'd rather trigger the events after
  379. # the pusher has had a chance to fix up our
  380. # position, so we never trigger things that are
  381. # behind other polygons.
  382. base.shadowTrav.addCollider(self.cEventSphereNodePath, self.event)
  383.  
  384. else:
  385. if hasattr(self, 'cTrav'):
  386. self.cTrav.removeCollider(self.cWallSphereNodePath)
  387. if self.wantFloorSphere:
  388. self.cTrav.removeCollider(self.cFloorSphereNodePath)
  389. self.cTrav.removeCollider(self.cEventSphereNodePath)
  390. base.shadowTrav.removeCollider(self.cEventSphereNodePath)
  391. base.shadowTrav.removeCollider(self.cRayNodePath)
  392.  
  393. def getCollisionsActive(self):
  394. assert self.debugPrint("getCollisionsActive() returning=%s"%(
  395. self.collisionsActive,))
  396. return self.collisionsActive
  397.  
  398. def placeOnFloor(self):
  399. """
  400. Make a reasonable effor to place the avatar on the ground.
  401. For example, this is useful when switching away from the
  402. current walker.
  403. """
  404. assert self.notify.debugStateCall(self)
  405. self.oneTimeCollide()
  406. self.avatarNodePath.setZ(self.avatarNodePath.getZ()-self.lifter.getAirborneHeight())
  407.  
  408. def oneTimeCollide(self):
  409. """
  410. Makes one quick collision pass for the avatar, for instance as
  411. a one-time straighten-things-up operation after collisions
  412. have been disabled.
  413. """
  414. assert self.notify.debugStateCall(self)
  415. if not hasattr(self, 'cWallSphereNodePath'):
  416. return
  417. self.isAirborne = 0
  418. self.mayJump = 1
  419. tempCTrav = CollisionTraverser("oneTimeCollide")
  420. tempCTrav.addCollider(self.cWallSphereNodePath, self.pusher)
  421. if self.wantFloorSphere:
  422. tempCTrav.addCollider(self.cFloorSphereNodePath, self.event)
  423. tempCTrav.addCollider(self.cRayNodePath, self.lifter)
  424. tempCTrav.traverse(render)
  425.  
  426. def setMayJump(self, task):
  427. """
  428. This function's use is internal to this class (maybe I'll add
  429. the __ someday). Anyway, if you want to enable or disable
  430. jumping in a general way see the ControlManager (don't use this).
  431. """
  432. assert self.notify.debugStateCall(self)
  433. self.mayJump = 1
  434. return Task.done
  435.  
  436. def startJumpDelay(self, delay):
  437. assert self.notify.debugStateCall(self)
  438. if self.jumpDelayTask:
  439. self.jumpDelayTask.remove()
  440. self.mayJump = 0
  441. self.jumpDelayTask=taskMgr.doMethodLater(
  442. delay,
  443. self.setMayJump,
  444. "jumpDelay-%s"%id(self))
  445.  
  446. def addBlastForce(self, vector):
  447. self.lifter.addVelocity(vector.length())
  448.  
  449. def displayDebugInfo(self):
  450. """
  451. For debug use.
  452. """
  453. onScreenDebug.add("w controls", "GravityWalker")
  454.  
  455. onScreenDebug.add("w airborneHeight", self.lifter.getAirborneHeight())
  456. onScreenDebug.add("w falling", self.falling)
  457. onScreenDebug.add("w isOnGround", self.lifter.isOnGround())
  458. #onScreenDebug.add("w gravity", self.lifter.getGravity())
  459. #onScreenDebug.add("w jumpForce", self.avatarControlJumpForce)
  460. onScreenDebug.add("w contact normal", self.lifter.getContactNormal().pPrintValues())
  461. onScreenDebug.add("w mayJump", self.mayJump)
  462. onScreenDebug.add("w impact", self.lifter.getImpactVelocity())
  463. onScreenDebug.add("w velocity", self.lifter.getVelocity())
  464. onScreenDebug.add("w isAirborne", self.isAirborne)
  465. onScreenDebug.add("w hasContact", self.lifter.hasContact())
  466.  
  467. def handleAvatarControls(self, task):
  468. """
  469. Check on the arrow keys and update the avatar.
  470. """
  471. # get the button states:
  472. run = inputState.isSet("run")
  473. forward = inputState.isSet("forward")
  474. reverse = inputState.isSet("reverse")
  475. turnLeft = inputState.isSet("turnLeft")
  476. turnRight = inputState.isSet("turnRight")
  477. slideLeft = inputState.isSet("slideLeft")
  478. slideRight = inputState.isSet("slideRight")
  479. jump = inputState.isSet("jump")
  480.  
  481. # Check for Auto-Run
  482. if 'localAvatar' in __builtins__:
  483. if base.localAvatar and base.localAvatar.getAutoRun():
  484. forward = 1
  485. reverse = 0
  486.  
  487. # Determine what the speeds are based on the buttons:
  488. self.speed=(forward and self.avatarControlForwardSpeed or
  489. reverse and -self.avatarControlReverseSpeed)
  490. # Slide speed is a scaled down version of forward speed
  491. # Note: you can multiply a factor in here if you want slide to
  492. # be slower than normal walk/run. Let's try full speed.
  493. #self.slideSpeed=(slideLeft and -self.avatarControlForwardSpeed*0.75 or
  494. # slideRight and self.avatarControlForwardSpeed*0.75)
  495. self.slideSpeed=(reverse and slideLeft and -self.avatarControlReverseSpeed*0.75 or
  496. reverse and slideRight and self.avatarControlReverseSpeed*0.75 or
  497. slideLeft and -self.avatarControlForwardSpeed*0.75 or
  498. slideRight and self.avatarControlForwardSpeed*0.75)
  499. self.rotationSpeed=not (slideLeft or slideRight) and (
  500. (turnLeft and self.avatarControlRotateSpeed) or
  501. (turnRight and -self.avatarControlRotateSpeed))
  502.  
  503. if self.speed and self.slideSpeed:
  504. self.speed *= GravityWalker.DiagonalFactor
  505. self.slideSpeed *= GravityWalker.DiagonalFactor
  506.  
  507. debugRunning = inputState.isSet("debugRunning")
  508. if(debugRunning):
  509. self.speed*=base.debugRunningMultiplier
  510. self.slideSpeed*=base.debugRunningMultiplier
  511. self.rotationSpeed*=1.25
  512.  
  513. if self.needToDeltaPos:
  514. self.setPriorParentVector()
  515. self.needToDeltaPos = 0
  516. if self.wantDebugIndicator:
  517. self.displayDebugInfo()
  518. if self.lifter.isOnGround():
  519. if self.isAirborne:
  520. self.isAirborne = 0
  521. assert self.debugPrint("isAirborne 0 due to isOnGround() true")
  522. impact = self.lifter.getImpactVelocity()
  523. if impact < -30.0:
  524. messenger.send("jumpHardLand")
  525. self.startJumpDelay(0.3)
  526. else:
  527. messenger.send("jumpLand")
  528. if impact < -5.0:
  529. self.startJumpDelay(0.2)
  530. # else, ignore the little potholes.
  531. assert self.isAirborne == 0
  532. self.priorParent = Vec3.zero()
  533. if jump and self.mayJump:
  534. # The jump button is down and we're close
  535. # enough to the ground to jump.
  536. self.lifter.addVelocity(self.avatarControlJumpForce)
  537. messenger.send("jumpStart")
  538. self.isAirborne = 1
  539. assert self.debugPrint("isAirborne 1 due to jump")
  540. else:
  541. if self.isAirborne == 0:
  542. assert self.debugPrint("isAirborne 1 due to isOnGround() false")
  543. self.isAirborne = 1
  544.  
  545. self.__oldPosDelta = self.avatarNodePath.getPosDelta(render)
  546. # How far did we move based on the amount of time elapsed?
  547. self.__oldDt = ClockObject.getGlobalClock().getDt()
  548. dt=self.__oldDt
  549.  
  550. # Check to see if we're moving at all:
  551. self.moving = self.speed or self.slideSpeed or self.rotationSpeed or (self.priorParent!=Vec3.zero())
  552. if self.moving:
  553. distance = dt * self.speed
  554. slideDistance = dt * self.slideSpeed
  555. rotation = dt * self.rotationSpeed
  556.  
  557. # Take a step in the direction of our previous heading.
  558. if distance or slideDistance or self.priorParent != Vec3.zero():
  559. # rotMat is the rotation matrix corresponding to
  560. # our previous heading.
  561. rotMat=Mat3.rotateMatNormaxis(self.avatarNodePath.getH(), Vec3.up())
  562. if self.isAirborne:
  563. forward = Vec3.forward()
  564. else:
  565. contact = self.lifter.getContactNormal()
  566. forward = contact.cross(Vec3.right())
  567. # Consider commenting out this normalize. If you do so
  568. # then going up and down slops is a touch slower and
  569. # steeper terrain can cut the movement in half. Without
  570. # the normalize the movement is slowed by the cosine of
  571. # the slope (i.e. it is multiplied by the sign as a
  572. # side effect of the cross product above).
  573. forward.normalize()
  574. self.vel=Vec3(forward * distance)
  575. if slideDistance:
  576. if self.isAirborne:
  577. right = Vec3.right()
  578. else:
  579. right = forward.cross(contact)
  580. # See note above for forward.normalize()
  581. right.normalize()
  582. self.vel=Vec3(self.vel + (right * slideDistance))
  583. self.vel=Vec3(rotMat.xform(self.vel))
  584. step=self.vel + (self.priorParent * dt)
  585. self.avatarNodePath.setFluidPos(Point3(
  586. self.avatarNodePath.getPos()+step))
  587. self.avatarNodePath.setH(self.avatarNodePath.getH()+rotation)
  588. else:
  589. self.vel.set(0.0, 0.0, 0.0)
  590. if self.moving or jump:
  591. messenger.send("avatarMoving")
  592. return Task.cont
  593.  
  594. def doDeltaPos(self):
  595. assert self.notify.debugStateCall(self)
  596. self.needToDeltaPos = 1
  597.  
  598. def setPriorParentVector(self):
  599. assert self.notify.debugStateCall(self)
  600. if __debug__:
  601. onScreenDebug.add("__oldDt", "% 10.4f"%self.__oldDt)
  602. onScreenDebug.add("self.__oldPosDelta",
  603. self.__oldPosDelta.pPrintValues())
  604. # avoid divide by zero crash - grw
  605. if self.__oldDt == 0:
  606. velocity = 0
  607. else:
  608. velocity = self.__oldPosDelta*(1.0/self.__oldDt)
  609. self.priorParent = Vec3(velocity)
  610. if __debug__:
  611. if self.wantDebugIndicator:
  612. onScreenDebug.add("priorParent", self.priorParent.pPrintValues())
  613.  
  614. def reset(self):
  615. assert self.notify.debugStateCall(self)
  616. self.lifter.setVelocity(0.0)
  617. self.priorParent=Vec3.zero()
  618.  
  619. def getVelocity(self):
  620. return self.vel
  621.  
  622. def enableAvatarControls(self):
  623. """
  624. Activate the arrow keys, etc.
  625. """
  626. assert self.notify.debugStateCall(self)
  627. assert self.collisionsActive
  628.  
  629. #*#if __debug__:
  630. #*# self.accept("control-f3", self.spawnTest) #*#
  631.  
  632. # remove any old
  633. if self.controlsTask:
  634. self.controlsTask.remove()
  635. # spawn the new task
  636. taskName = "AvatarControls-%s"%(id(self),)
  637. self.controlsTask = taskMgr.add(self.handleAvatarControls, taskName, 25)
  638.  
  639. self.isAirborne = 0
  640. self.mayJump = 1
  641.  
  642. if self.physVelocityIndicator:
  643. if self.indicatorTask:
  644. self.indicatorTask.remove()
  645. self.indicatorTask = taskMgr.add(
  646. self.avatarPhysicsIndicator,
  647. "AvatarControlsIndicator-%s"%(id(self),), 35)
  648.  
  649. def disableAvatarControls(self):
  650. """
  651. Ignore the arrow keys, etc.
  652. """
  653. assert self.notify.debugStateCall(self)
  654. if self.controlsTask:
  655. self.controlsTask.remove()
  656. self.controlsTask = None
  657. if self.indicatorTask:
  658. self.indicatorTask.remove()
  659. self.indicatorTask = None
  660. if self.jumpDelayTask:
  661. self.jumpDelayTask.remove()
  662. self.jumpDelayTask = None
  663.  
  664. if __debug__:
  665. self.ignore("control-f3") #*#
  666.  
  667.  
  668. def flushEventHandlers(self):
  669. if hasattr(self, 'cTrav'):
  670. self.pusher.flush()
  671. if self.wantFloorSphere:
  672. self.floorPusher.flush()
  673. self.event.flush()
  674. self.lifter.flush() # not currently defined or needed
  675.  
  676. if __debug__:
  677. def debugPrint(self, message):
  678. """for debugging"""
  679. return self.notify.debug(
  680. str(id(self))+' '+message)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement