DirectGeometry.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. from PandaModules import *
  2. from PandaObject import *
  3. import math
  4. X_AXIS = Vec3(1,0,0)
  5. Y_AXIS = Vec3(0,1,0)
  6. Z_AXIS = Vec3(0,0,1)
  7. NEG_X_AXIS = Vec3(-1,0,0)
  8. NEG_Y_AXIS = Vec3(0,-1,0)
  9. NEG_Z_AXIS = Vec3(0,0,-1)
  10. ZERO_VEC = ORIGIN = Vec3(0)
  11. UNIT_VEC = Vec3(1)
  12. ZERO_POINT = Point3(0)
  13. class LineNodePath(NodePath):
  14. def __init__(self, parent = None, **kw):
  15. # Initialize the superclass
  16. NodePath.__init__(self)
  17. if parent is None:
  18. parent = hidden
  19. # Attach a geomNode to the parent and set self to be
  20. # the resulting node path
  21. self.lineNode = GeomNode()
  22. self.assign(parent.attachNewNode( self.lineNode ))
  23. # Create a lineSegs object to hold the line
  24. ls = self.lineSegs = LineSegs()
  25. # Initialize the lineSegs parameters
  26. ls.setThickness( kw.get('thickness', 1.0) )
  27. ls.setColor( kw.get('colorVec', VBase4(1.0)) )
  28. def moveTo( self, *_args ):
  29. apply( self.lineSegs.moveTo, _args )
  30. def drawTo( self, *_args ):
  31. apply( self.lineSegs.drawTo, _args )
  32. def create( self, frameAccurate = 0 ):
  33. self.lineSegs.create( self.lineNode, frameAccurate )
  34. def reset( self ):
  35. self.lineSegs.reset()
  36. self.lineNode.clear()
  37. def isEmpty( self ):
  38. return self.lineSegs.isEmpty()
  39. def setThickness( self, thickness ):
  40. self.lineSegs.setThickness( thickness )
  41. def setColor( self, *_args ):
  42. apply( self.lineSegs.setColor, _args )
  43. def setVertex( self, *_args):
  44. apply( self.lineSegs.setVertex, _args )
  45. def setVertexColor( self, vertex, *_args ):
  46. apply( self.lineSegs.setVertexColor, (vertex,) + _args )
  47. def getCurrentPosition( self ):
  48. return self.lineSegs.getCurrentPosition()
  49. def getNumVertices( self ):
  50. return self.lineSegs.getNumVertices()
  51. def getVertex( self, index ):
  52. return self.lineSegs.getVertex(index)
  53. def getVertexColor( self ):
  54. return self.lineSegs.getVertexColor()
  55. def drawArrow(self, sv, ev, arrowAngle, arrowLength):
  56. """
  57. Do the work of moving the cursor around to draw an arrow from
  58. sv to ev. Hack: the arrows take the z value of the end point
  59. """
  60. self.moveTo(sv)
  61. self.drawTo(ev)
  62. v = sv - ev
  63. # Find the angle of the line
  64. angle = math.atan2(v[1], v[0])
  65. # Get the arrow angles
  66. a1 = angle + deg2Rad(arrowAngle)
  67. a2 = angle - deg2Rad(arrowAngle)
  68. # Get the arrow points
  69. a1x = arrowLength * math.cos(a1)
  70. a1y = arrowLength * math.sin(a1)
  71. a2x = arrowLength * math.cos(a2)
  72. a2y = arrowLength * math.sin(a2)
  73. z = ev[2]
  74. self.moveTo(ev)
  75. self.drawTo(Point3(ev + Point3(a1x, a1y, z)))
  76. self.moveTo(ev)
  77. self.drawTo(Point3(ev + Point3(a2x, a2y, z)))
  78. ##
  79. ## Given a point in space, and a direction, find the point of intersection
  80. ## of that ray with a plane at the specified origin, with the specified normal
  81. def planeIntersect (lineOrigin, lineDir, planeOrigin, normal):
  82. t = 0
  83. offset = planeOrigin - lineOrigin
  84. t = offset.dot(normal) / lineDir.dot(normal)
  85. hitPt = lineDir * t
  86. return hitPt + lineOrigin
  87. def ROUND_TO(value, divisor):
  88. return round(value/float(divisor)) * divisor
  89. def ROUND_INT(val):
  90. return int(round(val))
  91. def CLAMP(val, min, max):
  92. if val < min:
  93. return min
  94. elif val > max:
  95. return max
  96. else:
  97. return val
  98. def getNearProjectionPoint(nodePath):
  99. # Find the position of the projection of the specified node path
  100. # on the near plane
  101. origin = nodePath.getPos(direct.camera)
  102. # project this onto near plane
  103. if origin[1] != 0.0:
  104. return origin * (direct.dr.near / origin[1])
  105. else:
  106. # Object is coplaner with camera, just return something reasonable
  107. return Point3(0, direct.dr.near, 0)
  108. def getScreenXY(nodePath):
  109. # Where does the node path's projection fall on the near plane
  110. nearVec = getNearProjectionPoint(nodePath)
  111. # Clamp these coordinates to visible screen
  112. nearX = CLAMP(nearVec[0], direct.dr.left, direct.dr.right)
  113. nearY = CLAMP(nearVec[2], direct.dr.bottom, direct.dr.top)
  114. # What percentage of the distance across the screen is this?
  115. percentX = (nearX - direct.dr.left)/direct.dr.nearWidth
  116. percentY = (nearY - direct.dr.bottom)/direct.dr.nearHeight
  117. # Map this percentage to the same -1 to 1 space as the mouse
  118. screenXY = Vec3((2 * percentX) - 1.0,nearVec[1],(2 * percentY) - 1.0)
  119. # Return the resulting value
  120. return screenXY
  121. def getCrankAngle(center):
  122. # Used to compute current angle of mouse (relative to the coa's
  123. # origin) in screen space
  124. x = direct.dr.mouseX - center[0]
  125. y = direct.dr.mouseY - center[2]
  126. return (180 + rad2Deg(math.atan2(y,x)))
  127. def relHpr(nodePath, base, h, p, r):
  128. # Compute nodePath2newNodePath relative to base coordinate system
  129. # nodePath2base
  130. mNodePath2Base = nodePath.getMat(base)
  131. # delta scale, orientation, and position matrix
  132. mBase2NewBase = Mat4()
  133. composeMatrix(mBase2NewBase, UNIT_VEC, VBase3(h,p,r), ZERO_VEC,
  134. CSDefault)
  135. # base2nodePath
  136. mBase2NodePath = base.getMat(nodePath)
  137. # nodePath2 Parent
  138. mNodePath2Parent = nodePath.getMat()
  139. # Compose the result
  140. resultMat = mNodePath2Base * mBase2NewBase
  141. resultMat = resultMat * mBase2NodePath
  142. resultMat = resultMat * mNodePath2Parent
  143. # Extract and apply the hpr
  144. hpr = Vec3(0)
  145. decomposeMatrix(resultMat, VBase3(), hpr, VBase3(),
  146. CSDefault)
  147. nodePath.setHpr(hpr)
  148. # Set direct drawing style for an object
  149. # Never light object or draw in wireframe
  150. def useDirectRenderStyle(nodePath):
  151. nodePath.getBottomArc().setTransition(LightTransition.allOff())
  152. nodePath.setRenderModeFilled()