1
1
#!/usr/bin/env python3
2
2
3
- from math import pi , sin , cos
3
+ from math import pi , sin , cos , radians , hypot
4
4
from random import random , randint
5
+ from collections import defaultdict
5
6
7
+ from webcolors import hex_to_rgb
6
8
from hotqueue import HotQueue
7
9
8
10
import sys
36
38
""" )
37
39
exit (0 )
38
40
41
+ X_EXTENT = 32
42
+ Y_EXTENT = 24
43
+ Z_EXTENT = 18
44
+
39
45
def makeBoundaryBox (render , world ):
40
46
boundaryNode = BulletRigidBodyNode ("Boundary" )
41
47
boundaryNode .setFriction (0 )
@@ -47,12 +53,12 @@ def makeBoundaryBox(render, world):
47
53
cubeNp .attachNewNode (cubeNode )
48
54
49
55
for pos , shape in (
50
- ((0 , 0 , - 18 ), Vec3 (32 , 24 , 1 )),
51
- ((0 , 0 , 18 ), Vec3 (32 , 24 , 1 )),
52
- ((0 , - 24 , 0 ), Vec3 (32 , 1 , 18 )),
53
- ((0 , 24 , 0 ), Vec3 (32 , 1 , 18 )),
54
- ((- 32 , 0 , 0 ), Vec3 ( 1 , 24 , 18 )),
55
- (( 32 , 0 , 0 ), Vec3 ( 1 , 24 , 18 )),
56
+ ((0 , 0 , - Z_EXTENT ), Vec3 (X_EXTENT , Y_EXTENT , 1 )),
57
+ ((0 , 0 , Z_EXTENT ), Vec3 (X_EXTENT , Y_EXTENT , 1 )),
58
+ ((0 , - Y_EXTENT , 0 ), Vec3 (X_EXTENT , 1 , Z_EXTENT )),
59
+ ((0 , Y_EXTENT , 0 ), Vec3 (X_EXTENT , 1 , Z_EXTENT )),
60
+ ((- X_EXTENT , 0 , 0 ), Vec3 ( 1 , Y_EXTENT , Z_EXTENT )),
61
+ (( X_EXTENT , 0 , 0 ), Vec3 ( 1 , Y_EXTENT , Z_EXTENT )),
56
62
):
57
63
boundaryShape = BulletBoxShape (shape )
58
64
boundaryNode .addShape (boundaryShape ,
@@ -81,9 +87,12 @@ def __init__(self, parent, world, font=None):
81
87
m [1 ][1 ] = 0.1
82
88
self .textNode .setTransform (m )
83
89
90
+ self .halfExtents = (0 , 0 , 0 )
91
+
84
92
self .rbNode = BulletRigidBodyNode ("Text" )
85
93
self .rootNp = parent .attachNewNode (self .rbNode )
86
94
self .textNp = self .rootNp .attachNewNode (self .textNode )
95
+ self .textNp .setScale (1.8 )
87
96
88
97
self .rbNode .setFriction (0 )
89
98
self .rbNode .setRestitution (1 )
@@ -93,19 +102,32 @@ def __init__(self, parent, world, font=None):
93
102
self .rbNode .setDeactivationEnabled (False )
94
103
self .rbNode .setKinematic (True )
95
104
96
- world .attachRigidBody (self .rbNode )
105
+ world .attach (self .rbNode )
106
+ self .world = world
107
+
108
+ def destroy (self ):
109
+ self .rootNp .detachNode ()
110
+ self .world .remove (self .rbNode )
97
111
98
112
def setText (self , value ):
113
+ if hasattr (self , "bulletShape" ) and self .bulletShape :
114
+ self .rbNode .removeShape (self .bulletShape )
115
+ self .bulletShape = None
116
+
99
117
self .textNode .setText (value )
118
+ self .textNp .setPos (0 , 0 , 0 )
119
+ self .halfExtents = (0 , 0 , 0 )
100
120
101
- ul , lr = self .textNp .getTightBounds ()
102
- halfExtents = (lr - ul ) / 2
103
- self .textNp .setPos (- halfExtents - ul )
121
+ if self .textNp .getTightBounds ():
122
+ ul , lr = self .textNp .getTightBounds ()
123
+ self .halfExtents = (lr - ul ) / 2
124
+ self .textNp .setPos (- self .halfExtents - ul )
125
+
126
+ self .bulletShape = BulletBoxShape (self .halfExtents )
127
+ self .rbNode .addShape (self .bulletShape )
104
128
105
- if hasattr (self , "bulletShape" ):
106
- self .rbNode .removeShape (self .bulletShape )
107
- self .bulletShape = BulletBoxShape (halfExtents )
108
- self .rbNode .addShape (self .bulletShape )
129
+ def getHalfExtents (self ):
130
+ return self .halfExtents
109
131
110
132
def setColor (self , color ):
111
133
self .textNp .setColor (color )
@@ -116,6 +138,12 @@ def setPos(self, pos):
116
138
def setHpr (self , hpr ):
117
139
self .rootNp .setHpr (hpr )
118
140
141
+ def getPos (self ):
142
+ return self .rootNp .getPos ()
143
+
144
+ def getHpr (self ):
145
+ return self .rootNp .getHpr ()
146
+
119
147
def launch (self , linear , angular ):
120
148
self .rbNode .setKinematic (False )
121
149
self .rbNode .setLinearVelocity (linear )
@@ -162,12 +190,12 @@ def __init__(self):
162
190
163
191
self .textNp = self .render .attachNewNode ("TextNodes" )
164
192
165
- light = makeLight (2 )
193
+ light = makeLight (1 )
166
194
lightNp = render .attachNewNode (light )
167
195
lightNp .setPos (24 , - 30 , 12 )
168
196
self .textNp .setLight (lightNp )
169
197
170
- light = makeLight (2 )
198
+ light = makeLight (1 )
171
199
lightNp = render .attachNewNode (light )
172
200
lightNp .setPos (- 24 , - 30 , - 12 )
173
201
self .textNp .setLight (lightNp )
@@ -189,6 +217,10 @@ def __init__(self):
189
217
random () * 10 - 5 )))
190
218
self .accept ('l' , self .sampleLaunch )
191
219
220
+ self .launchers = defaultdict (
221
+ lambda : LaunchableText (self .textNp , self .world , self .font ))
222
+ self .floaters = []
223
+
192
224
self .targets = []
193
225
#self.createTarget("A", -2, 5, -1)
194
226
@@ -232,27 +264,81 @@ def toggleGravity(self):
232
264
print ("New Gravity: " , self .world .getGravity ())
233
265
234
266
def update (self , task ):
235
- dt = globalClock .getDt ()
236
- if not self .paused :
237
- self .world .doPhysics (dt )
238
-
239
267
msg = self .queue .get ()
240
268
processed = 0
241
269
while msg :
242
- print (msg )
243
- if msg ["props" ]["text" ]:
244
- if msg ["action" ] == "update" :
245
- self .processUpdate (msg )
246
- elif msg ["action" ] == "launch" :
247
- self .processUpdate (msg )
248
- self .processLaunch (msg )
270
+ if msg ["action" ] == "leave" :
271
+ self .launchers [msg ["client_id" ]].destroy ()
272
+ del self .launchers [msg ["client_id" ]]
273
+ elif msg ["action" ] == "update" :
274
+ self .processUpdate (msg )
275
+ elif msg ["action" ] == "launch" :
276
+ self .processUpdate (msg )
277
+ self .processLaunch (msg )
249
278
processed += 1
250
279
if processed < self .msgsPerFrameLimit :
251
280
msg = self .queue .get ()
252
281
else :
253
282
msg = None
283
+
284
+ dt = globalClock .getDt ()
285
+ if not self .paused :
286
+ self .world .doPhysics (dt )
254
287
return task .cont
255
288
289
+ def processUpdate (self , msg ):
290
+ props = msg ["props" ]
291
+ text = self .launchers [msg ["client_id" ]]
292
+ text .setText (props ["text" ])
293
+ text .setColor (Vec3 (* hex_to_rgb (props ["color" ])) / 256 )
294
+
295
+ props ["y" ] *= - 1
296
+ props ["z" ] *= - 1
297
+ if abs (props ["x" ]) != 1 and abs (props ["y" ]) != 1 :
298
+ if abs (props ["x" ]) > abs (props ["y" ]):
299
+ props ["x" ] = 1 if props ["x" ] > 0 else - 1
300
+ else :
301
+ props ["y" ] = 1 if props ["y" ] > 0 else - 1 ;
302
+
303
+ x = props ["x" ] * X_EXTENT * .95
304
+ y = props ["z" ] * Y_EXTENT * .92
305
+ z = props ["y" ] * Z_EXTENT * .90
306
+ if abs (props ["x" ]) == 1 :
307
+ x += text .getHalfExtents ()[0 ] * - props ["x" ]
308
+ if abs (props ["y" ]) == 1 :
309
+ z += text .getHalfExtents ()[0 ] * - props ["y" ]
310
+ props ["planarAngle" ] += 90 * props ["y" ]
311
+ text .setPos (Point3 (x , y , z ))
312
+
313
+ if abs (props ["x" ]) == 1 :
314
+ hpr = Vec3 (props ["zAngle" ], 0 , props ["planarAngle" ])
315
+ else :
316
+ hpr = Vec3 (0 , - props ["zAngle" ], props ["planarAngle" ])
317
+ text .setHpr (hpr )
318
+
319
+ def processLaunch (self , msg ):
320
+ props = msg ["props" ]
321
+ text = self .launchers [msg ["client_id" ]]
322
+
323
+ hpr = text .getHpr ()
324
+ if abs (props ["x" ]) == 1 :
325
+ velocity = Vec3 (
326
+ - props ["x" ] * cos (radians (hpr [0 ])) * cos (radians (hpr [2 ])),
327
+ - props ["x" ] * sin (radians (hpr [0 ])),
328
+ - props ["x" ] * - sin (radians (hpr [2 ])))
329
+ else :
330
+ velocity = Vec3 (
331
+ cos (radians (hpr [2 ])),
332
+ - sin (radians (hpr [1 ])),
333
+ - cos (radians (hpr [1 ])) * sin (radians (hpr [2 ])))
334
+
335
+ angular = Vec3 (random (), random (), random ())
336
+ text .launch (velocity * (props ["launchStrength" ] * 10 + 3 ),
337
+ angular * props ["launchStrength" ] * 0 )
338
+
339
+ self .floaters .append (text )
340
+ del self .launchers [msg ["client_id" ]]
341
+
256
342
def createTarget (self , name , x = 0 , y = 0 , z = 0 ):
257
343
shape = BulletSphereShape (0.5 )
258
344
ghost = BulletGhostNode ('GhostTarget_' + name )
0 commit comments