-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathtpick.cxs
271 lines (180 loc) · 5.85 KB
/
tpick.cxs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
''NOTES
'' needs TCollision to be ported over
Import minib3d
Import minib3d.math.geom
Import minib3d.tcollision
Class TPick
' EntityPickMode in TEntity
Const EPSILON=.0001
Global ent_list:List<TEntity>=New List<TEntity> ' list containing pickable entities
Global picked_x:Float,picked_y:Float,picked_z:Float
Global picked_nx:Float,picked_ny:Float,picked_nz:Float
Global picked_time:Float
Global picked_ent:TEntity
Global picked_surface:Int = -1
Global picked_triangle:Int
Global picked_pos:Vector
Global picked_norm:Vector
Global mat:Matrix=New Matrix
Global tform:TransformMat = New TransformMat()
Function CameraPick:TEntity(cam:TCamera,vx:Float,vy:Float)
Local vec:Vector
Local dvec:Vector
vy=cam.viewport[3]-vy
vec = cam.GluUnProject(vx,vy,0.0,cam)
dvec = cam.GluUnProject(vx,vy,1.0,cam)
Return Pick(vec.x,vec.y,-vec.z,dvec.x,dvec.y,-dvec.z,0.0)
End
Function EntityPick:TEntity(ent:TEntity,range:Float)
TEntity.TFormPoint(0.0,0.0,0.0,ent,Null)
Local x:Float=TEntity.TFormedX()
Local y:Float=TEntity.TFormedY()
Local z:Float=TEntity.TFormedZ()
TEntity.TFormPoint(0.0,0.0,range,ent,Null)
Local x2:Float=TEntity.TFormedX()
Local y2:Float=TEntity.TFormedY()
Local z2:Float=TEntity.TFormedZ()
Return Pick(x,y,z,x2,y2,z2)
End
Function LinePick:TEntity(x:Float,y:Float,z:Float,dx:Float,dy:Float,dz:Float,radius:Float=0.0)
Return Pick(x,y,z,x+dx,y+dy,z+dz,radius)
End
Function EntityVisible(src_ent:TEntity,dest_ent:TEntity)
' get pick values
Local px:Float=picked_x
Local py:Float=picked_y
Local pz:Float=picked_z
Local pnx:Float=picked_nx
Local pny:Float=picked_ny
Local pnz:Float=picked_nz
Local ptime:Float=picked_time
Local pent:TEntity=picked_ent
Local psurf:int=picked_surface
Local ptri=picked_triangle
' perform line pick
Local ax:Float=src_ent.EntityX(True)
Local ay:Float=src_ent.EntityY(True)
Local az:Float=src_ent.EntityZ(True)
Local bx:Float=dest_ent.EntityX(True)
Local by:Float=dest_ent.EntityY(True)
Local bz:Float=dest_ent.EntityZ(True)
Local pick:TEntity=Pick(ax,ay,az,bx,by,bz)
' if picked entity was dest ent then dest_picked flag to true
Local dest_picked=False
If picked_ent=dest_ent Then dest_picked=True
' restore pick values
picked_x=px
picked_y=py
picked_z=pz
picked_nx=pnx
picked_ny=pny
picked_nz=pnz
picked_time=ptime
picked_ent=pent
picked_surface=psurf
picked_triangle=ptri
' return false (not visible) if nothing picked, or dest ent wasn't picked
If pick<>Null And dest_picked<>True
Return False
Endif
Return True
End
Function PickedX:Float()
Return picked_x
End
Function PickedY:Float()
Return picked_y
End
Function PickedZ:Float()
Return picked_z
End
Function PickedNX:Float()
Return picked_nx
End
Function PickedNY:Float()
Return picked_ny
End
Function PickedNZ:Float()
Return picked_nz
End
Function PickedTime:Float()
Return picked_time
End
Function PickedEntity:TEntity()
Return picked_ent
End
Function PickedSurface:TSurface()
If picked_surface <0 Or Not picked_ent Then Return Null
Return TMesh(picked_ent).GetSurface(picked_surface)
End
Function PickedTriangle()
Return picked_triangle
End
Private
Global col_obj:CollisionObject = New CollisionObject()
Global col_info:CollisionInfo = New CollisionInfo()
Global vec_a:Vector =New Vector(0.0,0.0,0.0)
Global vec_b:Vector =New Vector(0.0,0.0,0.0)
Global vec_radius:Vector =New Vector(0.0,0.0,0.0)
Global vec_i:Vector =New Vector(0.0,0.0,0.0)
Global vec_j:Vector =New Vector(0.0,0.0,0.0)
Global vec_k:Vector =New Vector(0.0,0.0,0.0)
Global vec_v:Vector =New Vector(0.0,0.0,0.0)
Global nullVec:Vector = New Vector()
Public
' requires two absolute positional values
Function Pick:TEntity(ax:Float,ay:Float,az:Float,bx:Float,by:Float,bz:Float,s_radius:Float=0.0)
mat.LoadIdentity()
picked_ent=Null
picked_time=999999999999.0
Local pick:Int =False
''reset
col_obj.Clear()
col_info.ClearHitPlanes()
col_info.Clear()
Local cen:Vector = New Vector(0,0,0)
''coll ray info setup for pick
'Local col_info:CollisionInfo = New CollisionInfo()
col_info.UpdateRay(New Vector(ax,ay,az), New Vector(bx,by,bz), New Vector(s_radius,s_radius,s_radius) )
col_obj.time = picked_time
For Local ent:TEntity=Eachin ent_list
If ent.pick_mode=0 Or ent.Hidden()=True Then Continue
'If ent.collision.radius_x=0.0 Then col_info.UpdateSourceSphere(ent)
col_info.UpdateDestShape(ent)
col_info.coll_method = ent.pick_mode
''sphere center must be relative to ray
cen.Update(ent.mat.grid[3][0] - ax, ent.mat.grid[3][1] - ay,-ent.mat.grid[3][2] - az)
If col_obj.RaySphereTest(col_info.ray_dir, cen, col_info.dst_radius) > 0
col_info.UpdateDestShape(ent)
col_info.ray_length = col_info.dst_radius*3.0
col_info.CollisionSetup(ent, ent.pick_mode, col_obj, nullVec)
pick = col_info.CollisionDetect(col_obj)
If pick And col_obj.col_time<picked_time
picked_ent=ent
picked_time = col_obj.col_time
picked_pos = col_obj.col_coords
picked_norm = col_obj.col_normal
col_info.RegisterHitPlane ( col_obj.col_coords, col_obj.normal)
''do we need to run through the whole list? yes
Endif
endif
Next
If picked_ent<>Null
picked_x=picked_pos.x 'col_obj.col_coords.x
picked_y=picked_pos.y 'col_obj.col_coords.y
picked_z=picked_pos.z 'col_obj.col_coords.z
picked_nx=picked_norm.x 'col_obj.col_normal.x
picked_ny=picked_norm.y 'col_obj.col_normal.y
picked_nz=picked_norm.z 'col_obj.col_normal.z
picked_time=col_obj.col_time
'picked_ent=ent
If TMesh(picked_ent)<>Null
picked_surface=col_obj.surface '& $0000ffff
Else
picked_surface=-1
Endif
picked_triangle=col_obj.index
Endif
Return picked_ent
End
End