1
from pandac.PandaModules import CollisionHandlerQueue
2
from pandac.PandaModules import CollisionNode
3
from pandac.PandaModules import CollisionRay
4
from pandac.PandaModules import CollisionTraverser
5
from pandac.PandaModules import Geom
6
from pandac.PandaModules import GeomNode
7
from pandac.PandaModules import GeomTriangles
8
from pandac.PandaModules import GeomVertexData
9
from pandac.PandaModules import GeomVertexFormat
10
from pandac.PandaModules import GeomVertexWriter
11
from pandac.PandaModules import LineSegs
12
from pandac.PandaModules import NodePath
13
from pandac.PandaModules import Vec3
14
from pandac.PandaModules import Vec4
17
from GameConsts import *
18
from Util import frange
20
# Creates the grid overlay for the Universe.
21
# Grid implementation adapted from http://www.panda3d.org/phpbb2/viewtopic.php?t=3034
23
'''The grid object draws a bunch of lines and flattens them into a single
25
def __init__(self, parent, boardRad, gridInt):
26
Event.Dispatcher().register(self, 'E_Key_GridUp', self.gridMove)
27
Event.Dispatcher().register(self, 'E_Key_GridDown', self.gridMove)
30
self.gridInt = gridInt
31
self.boardRad = boardRad
33
if((boardRad*2) % gridInt is not 0):
34
print("ERROR: gridInt can not fit in universeRadius")
35
Event.Dispatcher().broadcast(Event.Event('E_ExitGame', src=self))
37
self.gridNP = NodePath("Grid Node Parent")
38
self.squareNP = NodePath("Squares Node Parent")
41
#Since we are using collision detection to do picking, we set it up like
42
#any other collision detection system with a traverser and a handler
43
self.picker = CollisionTraverser() #Make a traverser
44
self.pq = CollisionHandlerQueue() #Make a handler
45
#Make a collision node for our picker ray
46
self.pickerNode = CollisionNode('mouseRay')
47
#Attach that node to the camera since the ray will need to be positioned
49
self.pickerNP = camera.attachNewNode(self.pickerNode)
50
#Everything to be picked will use bit 1. This way if we were doing other
51
#collision we could seperate it
52
self.pickerNode.setFromCollideMask(BitMask32.bit(1))
53
self.pickerRay = CollisionRay() #Make our ray
54
self.pickerNode.addSolid(self.pickerRay) #Add it to the collision node
55
#Register the ray as something that can cause collisions
56
self.picker.addCollider(self.pickerNP, self.pq)
57
#self.picker.showCollisions(render)
61
self.drawLine(self.gridNP, Vec3(0, -boardRad, self.currZ), Vec3(0, boardRad, self.currZ))
62
self.drawLine(self.gridNP, Vec3(-boardRad, 0, self.currZ), Vec3(boardRad, 0, self.currZ))
63
# Draw lines in y-axis direction
64
for x in frange(gridInt, (boardRad + gridInt), gridInt):
65
self.drawLine(self.gridNP, Vec3(x, -boardRad, self.currZ), Vec3(x, boardRad, self.currZ))
66
self.drawLine(self.gridNP, Vec3(-x, -boardRad, self.currZ), Vec3(-x, boardRad, self.currZ))
67
# Draw lines in x-axis direction
68
for y in frange(gridInt, (boardRad + gridInt), gridInt):
69
self.drawLine(self.gridNP, Vec3(-boardRad, y, self.currZ), Vec3(boardRad, y, self.currZ))
70
self.drawLine(self.gridNP, Vec3(-boardRad, -y, self.currZ), Vec3(boardRad, -y, self.currZ))
72
self.gridNP.flattenStrong()
73
# Start with grids turned off
76
self.gridNP.reparentTo(parent)
79
# Draws a line from source to target and parents to parent
80
def drawLine(self, parent, source, target):
82
line.setThickness(LINETHICKNESS)
84
line.setColor(*GRIDCOLOR)
88
lineSegNP = NodePath(node).reparentTo(parent)
91
# Draws a square from ll (x1, y2, z1) to ur (x2, y2, z2) returns a node path
92
def drawSquare(self, x1,y1,z1, x2,y2,z2):
93
format=GeomVertexFormat.getV3n3cpt2()
94
vdata=GeomVertexData('square', format, Geom.UHStatic)
96
vertex=GeomVertexWriter(vdata, 'vertex')
97
normal=GeomVertexWriter(vdata, 'normal')
98
color=GeomVertexWriter(vdata, 'color')
99
texcoord=GeomVertexWriter(vdata, 'texcoord')
101
#make sure we draw the sqaure in the right plane
103
vertex.addData3f(x1, y1, z1)
104
vertex.addData3f(x2, y1, z1)
105
vertex.addData3f(x2, y2, z2)
106
vertex.addData3f(x1, y2, z2)
108
normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
109
normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
110
normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
111
normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
113
#adding different colors to the vertex for visibility
114
color.addData4f(0.0,0.5,0.0,0.5)
115
color.addData4f(0.0,0.5,0.0,0.5)
116
color.addData4f(0.0,0.5,0.0,0.5)
117
color.addData4f(0.0,0.5,0.0,0.5)
119
texcoord.addData2f(0.0, 1.0)
120
texcoord.addData2f(0.0, 0.0)
121
texcoord.addData2f(1.0, 0.0)
122
texcoord.addData2f(1.0, 1.0)
124
#quads arent directly supported by the Geom interface
125
#you might be interested in the CardMaker class if you are
126
#interested in rectangle though
127
tri1=GeomTriangles(Geom.UHStatic)
128
tri2=GeomTriangles(Geom.UHStatic)
134
tri2.addConsecutiveVertices(1,3)
136
tri1.closePrimitive()
137
tri2.closePrimitive()
140
square.addPrimitive(tri1)
141
square.addPrimitive(tri2)
142
#square.setIntoCollideMask(BitMask32.bit(1))
144
squareNP = NodePath(GeomNode('square gnode'))
145
squareNP.node().addGeom(square)
146
squareNP.setTransparency(1)
147
squareNP.setAlphaScale(.5)
148
squareNP.setTwoSided(True)
149
squareNP.setCollideMask(BitMask32.bit(1))
153
# Calculates a normal (How?)
154
def myNormalize(self, myVec):
158
def gridMove(self, event):
160
if event.type == 'E_Key_GridUp':
161
self.gridNP.setPos(self.gridNP.getX(), self.gridNP.getY(), self.currZ + self.gridInt)
162
if event.type == 'E_Key_GridDown':
163
self.gridNP.setPos(self.gridNP.getX(), self.gridNP.getY(), self.currZ - self.gridInt)
166
# Toggles between grid layers and grid off
167
def toggleState(self):
168
if (S.currLayer == 0):
170
self.gridNPList[0].show()
171
elif(S.currLayer == universeLayers):
172
self.gridNPList[S.currLayer-1].hide()
175
self.gridNPList[S.currLayer-1].hide()
176
S.currLayer = S.currLayer + 1
177
self.gridNPList[S.currLayer-1].show()