90d7d3fea14def966b51d7eb24a9f41fe541e786
1 from panda3d
.core
import CullFaceAttrib
, Point3
, NodePath
, Point2
, Texture
2 from panda3d
.bullet
import BulletBoxShape
, BulletRigidBodyNode
3 from direct
.gui
.OnscreenText
import OnscreenText
4 from lib
.lib
.p3d
.gfx
import P3dGfxMgr
8 def __init__(self
, world
, plane_node
, count
, cb_inst
):
10 self
._plane
_node
= plane_node
12 self
._cb
_inst
= cb_inst
13 shape
= BulletBoxShape((.5, .5, .5))
14 self
.node
= BulletRigidBodyNode('box')
15 self
.node
.add_shape(shape
)
16 self
._np
= render
.attach_new_node(self
.node
)
17 world
.attach_rigid_body(self
.node
)
18 model
= loader
.load_model('assets/gltf/box/box.gltf')
20 model
.reparent_to(self
._np
)
21 self
._set
_outline
_model
()
22 self
._start
_drag
_pos
= None
23 self
._prev
_rot
_info
= None
24 self
._instantiated
= False
25 taskMgr
.add(self
.on_frame
, 'on_frame')
29 p_from
, p_to
= P3dGfxMgr
.world_from_to((-1, 1))
30 for hit
in self
._world
.ray_test_all(p_from
, p_to
).get_hits():
31 if hit
.get_node() == self
._plane
_node
:
32 pos
= hit
.get_hit_pos()
33 corner
= P3dGfxMgr
.screen_coord(pos
)
34 bounds
= self
._np
.get_tight_bounds()
35 bounds
= bounds
[0] - self
._np
.get_pos(), bounds
[1] - self
._np
.get_pos()
38 def __update(set, get
, delta
):
40 top_left
= self
._np
.get_pos() + (bounds
[0][0], bounds
[0][1], bounds
[1][2])
41 tl2d
= P3dGfxMgr
.screen_coord(top_left
)
42 tmpnode
= NodePath('tmp')
43 tmpnode
.set_pos(tl2d
[0], 0, tl2d
[1])
44 cornernode
= NodePath('corner')
45 cornernode
.set_pos(corner
[0], 0, corner
[1])
46 dist
= tmpnode
.get_pos(cornernode
)
48 cornernode
.remove_node()
51 dist
= __update(self
._np
.set_x
, self
._np
.get_x
, .01)
53 dist
= __update(self
._np
.set_z
, self
._np
.get_z
, -.01)
54 if not hasattr(self
, '_txt'):
55 font
= base
.loader
.load_font('assets/fonts/Hanken-Book.ttf')
57 font
.set_pixels_per_unit(60)
58 font
.set_minfilter(Texture
.FTLinearMipmapLinear
)
59 font
.set_outline((0, 0, 0, 1), .8, .2)
60 self
._txt
= OnscreenText(
61 str(self
._count
), font
=font
, scale
=0.06, fg
=(.9, .9, .9, 1))
62 pos
= self
._np
.get_pos() + (bounds
[1][0], bounds
[0][1], bounds
[0][2])
63 p2d
= P3dGfxMgr
.screen_coord(pos
)
64 self
._txt
['pos'] = p2d
67 bounds
= self
._np
.get_tight_bounds()
68 return bounds
[1][0], bounds
[1][1], bounds
[0][2]
70 def _set_outline_model(self
):
71 self
._outline
_model
= loader
.load_model('assets/gltf/box/box.gltf')
72 clockw
= CullFaceAttrib
.MCullClockwise
73 self
._outline
_model
.set_attrib(CullFaceAttrib
.make(clockw
))
74 self
._outline
_model
.reparent_to(self
._np
)
75 self
._outline
_model
.set_scale(-1.08, -1.08, -1.08)
76 self
._outline
_model
.set_light_off()
77 self
._outline
_model
.set_color(.4, .4, .4, 1)
78 self
._outline
_model
.set_color_scale(.4, .4, .4, 1)
79 self
._outline
_model
.hide()
81 def on_frame(self
, task
):
86 self
._world
.remove_rigid_body(self
.node
)
88 self
._world
.attach_rigid_body(self
.node
)
90 def on_click_l(self
, pos
):
91 self
._start
_drag
_pos
= pos
, self
._np
.get_pos()
92 loader
.load_sfx('assets/audio/sfx/grab.ogg').play()
93 if not self
._instantiated
:
94 self
._instantiated
= True
98 box
= Box(self
._world
, self
._plane
_node
, self
._count
, self
._cb
_inst
)
101 def on_click_r(self
, pos
):
102 self
._prev
_rot
_info
= pos
, self
._np
.get_pos(), self
._np
.get_r()
103 loader
.load_sfx('assets/audio/sfx/grab.ogg').play()
105 def on_release(self
):
106 if self
._start
_drag
_pos
or self
._prev
_rot
_info
:
107 loader
.load_sfx('assets/audio/sfx/release.ogg').play()
108 self
._start
_drag
_pos
= self
._prev
_rot
_info
= None
110 def on_mouse_on(self
):
111 self
._outline
_model
.show()
113 def on_mouse_off(self
):
114 if self
._start
_drag
_pos
or self
._prev
_rot
_info
: return
115 self
._outline
_model
.hide()
117 def on_mouse_move(self
, pos
):
118 if self
._start
_drag
_pos
:
119 d_pos
= pos
- self
._start
_drag
_pos
[0]
120 self
._np
.set_pos(self
._start
_drag
_pos
[1] + d_pos
)
121 if self
._prev
_rot
_info
:
122 start_vec
= self
._prev
_rot
_info
[0] - self
._prev
_rot
_info
[1]
123 curr_vec
= pos
- self
._prev
_rot
_info
[1]
124 d_angle
= curr_vec
.signed_angle_deg(start_vec
, (0, -1, 0))
125 self
._np
.set_r(self
._prev
_rot
_info
[2] + d_angle
)
126 self
._prev
_rot
_info
= pos
, self
._np
.get_pos(), self
._np
.get_r()
128 def on_aspect_ratio_changed(self
):
129 if not self
._instantiated
: