# HG changeset patch # User Robert McIntyre # Date 1329087631 25200 # Node ID 267add63b1685c9a003f2437fa770b36b2fff4dd # Parent 4e220c8fb1eda7e163dc77e1250ce525aae0123b minor fixes diff -r 4e220c8fb1ed -r 267add63b168 org/touch.org --- a/org/touch.org Sun Feb 12 15:46:01 2012 -0700 +++ b/org/touch.org Sun Feb 12 16:00:31 2012 -0700 @@ -11,10 +11,6 @@ Touch is critical to navigation and spatial reasoning and as such I need a simulated version of it to give to my AI creatures. -However, touch in my virtual can not exactly correspond to human touch -because my creatures are made out of completely rigid segments that -don't deform like human skin. - Human skin has a wide array of touch sensors, each of which speciliaze in detecting different vibrational modes and pressures. These sensors can integrate a vast expanse of skin (i.e. your entire palm), or a @@ -22,15 +18,19 @@ help detect objects before they even come into contact with the skin proper. +However, touch in my simulated world can not exactly correspond to +human touch because my creatures are made out of completely rigid +segments that don't deform like human skin. + Instead of measuring deformation or vibration, I surround each rigid part with a plenitude of hair-like objects (/feelers/) which do not interact with the physical world. Physical objects can pass through -them with no effect. The feelers are able to measure contact with -other objects, and constantly report how much of their extent is -covered. So, even though the creature's body parts do not deform, the -feelers create a margin around those body parts which achieves a sense -of touch which is a hybrid between a human's sense of deformation and -sense from hairs. +them with no effect. The feelers are able to tell when other objects +pass through them, and they constantly report how much of their extent +is covered. So even though the creature's body parts do not deform, +the feelers create a margin around those body parts which achieves a +sense of touch which is a hybrid between a human's sense of +deformation and sense from hairs. Implementing touch in jMonkeyEngine follows a different techinal route than vision and hearing. Those two senses piggybacked off @@ -80,14 +80,14 @@ paramater which define the position and length of the feelers. Then, you use the triangles which compose the mesh and the UV data stored in the mesh to determine the world-space position and orientation of each -feeler. Once every frame, update these positions and orientations to -match the current position and orientation of the object, and use +feeler. Then once every frame, update these positions and orientations +to match the current position and orientation of the object, and use physics collision detection to gather tactile data. Extracting the meta-data has already been described. The third step, physics collision detection, is handled in =(touch-kernel)=. Translating the positions and orientations of the feelers from the -UV-map to world-space is also a three-step process. +UV-map to world-space is itself a three-step process. - Find the triangles which make up the mesh in pixel-space and in world-space. =(triangles)= =(pixel-triangles)=. @@ -121,15 +121,17 @@ (apply #(Triangle. %1 %2 %3) (map ->vector3f points))) #+end_src -It is convienent to treat a =Triangle= as a sequence of verticies, and -a =Vector2f= and =Vector3f= as a sequence of floats. These conversion -functions make this easy. If these classes implemented =Iterable= then -=(seq)= would work on them automitacally. +It is convienent to treat a =Triangle= as a vector of vectors, and a +=Vector2f= and =Vector3f= as vectors of floats. (->vector3f) and +(->triangle) undo the operations of =(vector3f-seq)= and +=(triangle-seq)=. If these classes implemented =Iterable= then =(seq)= +would work on them automitacally. + ** Decomposing a 3D shape into Triangles -The rigid bodies which make up a creature have an underlying +The rigid objects which make up a creature have an underlying =Geometry=, which is a =Mesh= plus a =Material= and other important -data involved with displaying the body. +data involved with displaying the object. A =Mesh= is composed of =Triangles=, and each =Triangle= has three verticies which have coordinates in world space and UV space. @@ -182,26 +184,28 @@ (map (partial vertex-UV-coord mesh) (triangle-vertex-indices mesh index)))))) -(defn pixel-triangles [#^Geometry geo image] - (let [height (.getHeight image) - width (.getWidth image)] - (map (partial pixel-triangle geo image) - (range (.getTriangleCount (.getMesh geo)))))) +(defn pixel-triangles + "The pixel-space triangles of the Geometry, in the same order as + (triangles geo)" + [#^Geometry geo image] + (let [height (.getHeight image) + width (.getWidth image)] + (map (partial pixel-triangle geo image) + (range (.getTriangleCount (.getMesh geo)))))) #+end_src ** The Affine Transform from one Triangle to Another =(pixel-triangles)= gives us the mesh triangles expressed in pixel coordinates and =(triangles)= gives us the mesh triangles expressed in world coordinates. The tactile-sensor-profile gives the position of -each feeler in pixel-space. In order to convert pixel-dpace +each feeler in pixel-space. In order to convert pixel-space coordinates into world-space coordinates we need something that takes coordinates on the surface of one triangle and gives the corresponding coordinates on the surface of another triangle. Triangles are [[http://mathworld.wolfram.com/AffineTransformation.html ][affine]], which means any triangle can be transformed into any other by a combination of translation, scaling, and -rotation. jMonkeyEngine's =Matrix4f= objects can describe any affine -transformation. The affine transformation from one triangle to another +rotation. The affine transformation from one triangle to another is readily computable if the triangle is expressed in terms of a $4x4$ matrix. @@ -221,7 +225,9 @@ $T_{2}T_{1}^{-1}$ -The clojure code below recaptiulates the formulas above. +The clojure code below recaptiulates the formulas above, using +jMonkeyEngine's =Matrix4f= objects, which can describe any affine +transformation. #+name: triangles-3 #+begin_src clojure