comparison org/test-creature.org @ 156:e8df6e76c3e5

refactored touch
author Robert McIntyre <rlm@mit.edu>
date Fri, 03 Feb 2012 06:15:34 -0700
parents 95bf55614211
children 84c67be00abe
comparison
equal deleted inserted replaced
155:95bf55614211 156:e8df6e76c3e5
75 [#^Vector3f in] 75 [#^Vector3f in]
76 (Vector3f. (.getX in) 76 (Vector3f. (.getX in)
77 (.getZ in) 77 (.getZ in)
78 (- (.getY in)))) 78 (- (.getY in))))
79 79
80 (defn world-to-local
81 "Convert the world coordinates into coordinates relative to the
82 object (i.e. local coordinates), taking into account the rotation
83 of object."
84 [#^Spatial object world-coordinate]
85 (.worldToLocal object world-coordinate nil))
86
87 (defn local-to-world
88 "Convert the local coordinates into coordinates into world relative
89 coordinates"
90 [#^Spatial object local-coordinate]
91 (.localToWorld object local-coordinate nil))
92 80
93 (defmulti joint-dispatch 81 (defmulti joint-dispatch
94 "Translate blender pseudo-joints into real JME joints." 82 "Translate blender pseudo-joints into real JME joints."
95 (fn [constraints & _] 83 (fn [constraints & _]
96 (:type constraints))) 84 (:type constraints)))
243 231
244 (def hand "Models/creature1/one.blend") 232 (def hand "Models/creature1/one.blend")
245 233
246 (def worm "Models/creature1/try-again.blend") 234 (def worm "Models/creature1/try-again.blend")
247 235
248 (def touch "Models/creature1/touch.blend")
249
250 (defn worm-model [] (load-blender-model worm)) 236 (defn worm-model [] (load-blender-model worm))
251 237
252 (defn x-ray [#^ColorRGBA color] 238 (defn x-ray [#^ColorRGBA color]
253 (doto (Material. (asset-manager) 239 (doto (Material. (asset-manager)
254 "Common/MatDefs/Misc/Unshaded.j3md") 240 "Common/MatDefs/Misc/Unshaded.j3md")
261 247
262 (import jme3tools.converters.ImageToAwt) 248 (import jme3tools.converters.ImageToAwt)
263 249
264 (import ij.ImagePlus) 250 (import ij.ImagePlus)
265 251
266 ;; Every Mesh has many triangles, each with its own index.
267 ;; Every vertex has its own index as well.
268
269 (defn tactile-sensor-image
270 "Return the touch-sensor distribution image in BufferedImage format,
271 or nil if it does not exist."
272 [#^Geometry obj]
273 (if-let [image-path (meta-data obj "touch")]
274 (ImageToAwt/convert
275 (.getImage
276 (.loadTexture
277 (asset-manager)
278 image-path))
279 false false 0)))
280
281
282
283 (defn triangle
284 "Get the triangle specified by triangle-index from the mesh within
285 bounds."
286 [#^Mesh mesh triangle-index]
287 (let [scratch (Triangle.)]
288 (.getTriangle mesh triangle-index scratch)
289 scratch))
290
291 (defn triangle-vertex-indices
292 "Get the triangle vertex indices of a given triangle from a given
293 mesh."
294 [#^Mesh mesh triangle-index]
295 (let [indices (int-array 3)]
296 (.getTriangle mesh triangle-index indices)
297 (vec indices)))
298
299 (defn vertex-UV-coord
300 "Get the uv-coordinates of the vertex named by vertex-index"
301 [#^Mesh mesh vertex-index]
302 (let [UV-buffer
303 (.getData
304 (.getBuffer
305 mesh
306 VertexBuffer$Type/TexCoord))]
307 [(.get UV-buffer (* vertex-index 2))
308 (.get UV-buffer (+ 1 (* vertex-index 2)))]))
309
310 (defn triangle-UV-coord
311 "Get the uv-cooridnates of the triangle's verticies."
312 [#^Mesh mesh width height triangle-index]
313 (map (fn [[u v]] (vector (* width u) (* height v)))
314 (map (partial vertex-UV-coord mesh)
315 (triangle-vertex-indices mesh triangle-index))))
316
317 (defn same-side?
318 "Given the points p1 and p2 and the reference point ref, is point p
319 on the same side of the line that goes through p1 and p2 as ref is?"
320 [p1 p2 ref p]
321 (<=
322 0
323 (.dot
324 (.cross (.subtract p2 p1) (.subtract p p1))
325 (.cross (.subtract p2 p1) (.subtract ref p1)))))
326
327 (defn triangle-seq [#^Triangle tri]
328 [(.get1 tri) (.get2 tri) (.get3 tri)])
329
330 (defn vector3f-seq [#^Vector3f v]
331 [(.getX v) (.getY v) (.getZ v)])
332
333 (defn inside-triangle?
334 "Is the point inside the triangle?"
335 {:author "Dylan Holmes"}
336 [#^Triangle tri #^Vector3f p]
337 (let [[vert-1 vert-2 vert-3] (triangle-seq tri)]
338 (and
339 (same-side? vert-1 vert-2 vert-3 p)
340 (same-side? vert-2 vert-3 vert-1 p)
341 (same-side? vert-3 vert-1 vert-2 p))))
342
343 (defn triangle->matrix4f
344 "Converts the triangle into a 4x4 matrix: The first three columns
345 contain the vertices of the triangle; the last contains the unit
346 normal of the triangle. The bottom row is filled with 1s."
347 [#^Triangle t]
348 (let [mat (Matrix4f.)
349 [vert-1 vert-2 vert-3]
350 ((comp vec map) #(.get t %) (range 3))
351 unit-normal (do (.calculateNormal t)(.getNormal t))
352 vertices [vert-1 vert-2 vert-3 unit-normal]]
353 (dorun
354 (for [row (range 4) col (range 3)]
355 (do
356 (.set mat col row (.get (vertices row)col))
357 (.set mat 3 row 1))))
358 mat))
359
360 (defn triangle-transformation
361 "Returns the affine transformation that converts each vertex in the
362 first triangle into the corresponding vertex in the second
363 triangle."
364 [#^Triangle tri-1 #^Triangle tri-2]
365 (.mult
366 (triangle->matrix4f tri-2)
367 (.invert (triangle->matrix4f tri-1))))
368
369 (defn point->vector2f [[u v]]
370 (Vector2f. u v))
371
372 (defn vector2f->vector3f [v]
373 (Vector3f. (.getX v) (.getY v) 0))
374
375 (defn map-triangle [f #^Triangle tri]
376 (Triangle.
377 (f 0 (.get1 tri))
378 (f 1 (.get2 tri))
379 (f 2 (.get3 tri))))
380
381 (defn points->triangle
382 "Convert a list of points into a triangle."
383 [points]
384 (apply #(Triangle. %1 %2 %3)
385 (map (fn [point]
386 (let [point (vec point)]
387 (Vector3f. (get point 0 0)
388 (get point 1 0)
389 (get point 2 0))))
390 (take 3 points))))
391
392 (defn convex-bounds
393 ;;dylan
394 "Returns the smallest square containing the given
395 vertices, as a vector of integers [left top width height]."
396 ;; "Dimensions of the smallest integer bounding square of the list of
397 ;; 2D verticies in the form: [x y width height]."
398 [uv-verts]
399 (let [xs (map first uv-verts)
400 ys (map second uv-verts)
401 x0 (Math/floor (apply min xs))
402 y0 (Math/floor (apply min ys))
403 x1 (Math/ceil (apply max xs))
404 y1 (Math/ceil (apply max ys))]
405 [x0 y0 (- x1 x0) (- y1 y0)]))
406
407 (defn sensors-in-triangle
408 ;;dylan
409 "Locate the touch sensors in the triangle, returning a map of their UV and geometry-relative coordinates."
410 ;;"Find the locations of the touch sensors within a triangle in both
411 ;; UV and gemoetry relative coordinates."
412 [image mesh tri-index]
413 (let [width (.getWidth image)
414 height (.getHeight image)
415 UV-vertex-coords (triangle-UV-coord mesh width height tri-index)
416 bounds (convex-bounds UV-vertex-coords)
417
418 cutout-triangle (points->triangle UV-vertex-coords)
419 UV-sensor-coords
420 (filter (comp (partial inside-triangle? cutout-triangle)
421 (fn [[u v]] (Vector3f. u v 0)))
422 (white-coordinates image bounds))
423 UV->geometry (triangle-transformation
424 cutout-triangle
425 (triangle mesh tri-index))
426 geometry-sensor-coords
427 (map (fn [[u v]] (.mult UV->geometry (Vector3f. u v 0)))
428 UV-sensor-coords)]
429 {:UV UV-sensor-coords :geometry geometry-sensor-coords}))
430
431 (defn-memo locate-feelers
432 "Search the geometry's tactile UV image for touch sensors, returning
433 their positions in geometry-relative coordinates."
434 [#^Geometry geo]
435 (let [mesh (.getMesh geo)
436 num-triangles (.getTriangleCount mesh)]
437 (if-let [image (tactile-sensor-image geo)]
438 (map
439 (partial sensors-in-triangle image mesh)
440 (range num-triangles))
441 (repeat (.getTriangleCount mesh) {:UV nil :geometry nil}))))
442
443 (use 'clojure.contrib.def)
444
445 (defn-memo touch-topology [#^Gemoetry geo]
446 (vec (collapse (reduce concat (map :UV (locate-feelers geo))))))
447
448 (defn-memo feeler-coordinates [#^Geometry geo]
449 (vec (map :geometry (locate-feelers geo))))
450
451 (defn enable-touch [#^Geometry geo]
452 (let [feeler-coords (feeler-coordinates geo)
453 tris (triangles geo)
454 limit 0.1
455 ;;results (CollisionResults.)
456 ]
457 (if (empty? (touch-topology geo))
458 nil
459 (fn [node]
460 (let [sensor-origins
461 (map
462 #(map (partial local-to-world geo) %)
463 feeler-coords)
464 triangle-normals
465 (map (partial get-ray-direction geo)
466 tris)
467 rays
468 (flatten
469 (map (fn [origins norm]
470 (map #(doto (Ray. % norm)
471 (.setLimit limit)) origins))
472 sensor-origins triangle-normals))]
473 (vector
474 (touch-topology geo)
475 (vec
476 (for [ray rays]
477 (do
478 (let [results (CollisionResults.)]
479 (.collideWith node ray results)
480 (let [touch-objects
481 (filter #(not (= geo (.getGeometry %)))
482 results)]
483 (- 255
484 (if (empty? touch-objects) 255
485 (rem
486 (int
487 (* 255 (/ (.getDistance
488 (first touch-objects)) limit)))
489 256))))))))))))))
490
491
492 (defn touch [#^Node pieces]
493 (filter (comp not nil?)
494 (map enable-touch
495 (filter #(isa? (class %) Geometry)
496 (node-seq pieces)))))
497 252
498 253
499 (defn test-eye [] 254 (defn test-eye []
500 (.getChild 255 (.getChild
501 (.getChild (worm-model) "eyes") 256 (.getChild (worm-model) "eyes")