Hiya!

If you already HAVE the h/v then its fairly easy:


------------------------------------------------------------
--ghSetColorAt3DCollision
------------------------------------------------------------
--Purpose: takes information from a raytrace collision and
--returns the color of the texture of the pixel at that 
--point on the object (reverse texture lookup)
------------------------------------------------------------
on ghSetColorAt3DCollision a_vHitPosition, a_aTriangle, \
                          a_aTexCoords, a_mModel, a_rgbColor
  
  
  --get texture from this model
  sTexName = a_mModel.shader.texture.name
  --should worry about whether this image exists in cast...
  imgTexImg = member(sTexName).image
  
  fX = ((imgTexImg.width-1) * a_aTexCoord[1])
  fY = imgTexImg.width - (((imgTexImg.width-1) * a_aTexCoord[2]))
  
  --setColor out of image and return
  imgTexImg.setPixel(fX, fY, a_rgbColor)
  
  a_mModel.shader.texture.image = imgTexImg
  
  updatestage
  
end ghGetColorFrom3DCollision
------------------------------------------------------------


If you DON'T already have the h/v, and only have position, and don't want to 
blindly use the h/v from modelsUnderRay, then it's a little harder:

(Pasting this bit from a private conversation)


[someone] is right - it is "barycentric something". More specifically, it is 
barycentric co-ordinates, which define a point as a point relative to the 3 
vertices of a triangle. More correct still, it is a vector (which may or may 
not be normalized but whose
sum = 1) . You can normalize barycentric coordinates such that the vector's 
elements represent the normalized area of the three smaller triangles created 
inside the larger one by drawing a line from the point to each of the 3 
vertices. For the geek
crowd, it is generally believed that barycentric coordiantes were discovered by 
Mobius in 1827. 

so AS I WAS SAYING...

The problem [someone] was having is that several methods for finding 
barycentric coordinates depend on the winding order of the triangle - so for 
backfacing triangles and/or every other triangle in a mesh, they will be 
backwards. That is no fun, so here is a
method that works the same regardless of winding order:

--code based on discussion by David Watson, on comp.graphics
--b0 = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)
--b1 = ((x2 - x0) * (y3 - y0) - (x3 - x0) * (y2 - y0)) / b0 
--b2 = ((x3 - x0) * (y1 - y0) - (x1 - x0) * (y3 - y0)) / b0
--b3 = ((x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)) / b0 
--baryC = vector(b1, b2, b3)


(interesting side note, if all components of the vector are > 0 then P is 
guaranteed to be within the triangle)
unfortunately, you all want to go from 3D into 2D, and not 2D into 3D (which is 
what I was doing with the above) so I had to work up another method for y'all.

When you fire a modelsUnderRay or modelsUnderLoc you generally get a structure 
back that looks something like this:

-- [[#model: model("Plane2"), #distance: 206.7631, #isectPosition: vector( 
-150.0000, 111.7515, 149.9010 ), #isectNormal: vector( 1.0000, 0.0000, 0.0000 
), #meshID: 1, #faceID: 2, #vertices: [vector( -150.0000, 250.0000, -150.0000 
), vector( -150.0000,
250.0000, 150.0000 ), vector( -150.0000, -50.0000, 150.0000 )], #uvCoord: [#u: 
0.5388, #V: 0.4608]]]

Note two things: the #isectPosition, and the #vertices array.

This means that we have a point on that triangle (#isectPosition) that I will 
now refer to as P. We also have the 3 points that make up the points that form 
the triangle that we think we struck. So we can produce a vector that 
represents P in
barycentric form. Like this:

on mCompute3DBarycentricCoordinates me, V0, V1, V2, P

--triangle ABC, points are V0, V1, V2
--along with a point, P (inside it, and planar, plz)

u = V1 - V0
v = V2 - V0
w = P - V0

d = (power(u.dot(v), 2) - (u.dot(u))*(v.dot(v))) --denominator
s = ((u.dot(v))*(w.dot(v)) - (v.dot(v))*(w.dot(u))) / d
t = ((u.dot(v))*(w.dot(u)) - (u.dot(u))*(w.dot(v))) / d

w = s*u + t*v --unique if P lies within the plane of ABC
b0 = (1-s-t)
b1 = s
b2 = t

me.vBaryC = vector(b0, b1, b2)

end mCompute3DBarycentricCoordinates

Wasn't that cool? Ugggh... many many nights figuring that stupid thing out, 
very frustrating. You will find that you need to *negate the Y component* of 
the vertices of the triangle (V0, V1, V2) in order to get the texture mapping 
correct. Why? Well...
because. That's all I will say about that until I write the paper, because I'm 
honestly not sure exactly what Director is doing under the hood that it is 
necessary, other than that it works. An oddity. Also please note, that I am 
feeding that handler
the positions of the point, and the vertices in WORLD SPACE. This is the way 
that they usually come back from the modelsUnderRay command, but its important 
to note since giving it one in model space and one in world space will really 
mess it up.

So now that we have that vector, we can think of those Barycentric coordinates 
as *weights* that describe the position of P relative to the 3 points of the 
triangle. The magic is that these weights are the EXACT SAME in 2D as in 3D. We 
already know
(hopefully from a #meshDeform or a #mesh modelResource, and by using the 
#meshID and #faceID returned) that the 3 points of the face we hit maps to a 
tuple of UVs, such that V0 -> UV0, V1 -> UV1, V2 -> UV2. So we can find the 
exact UV for point P
relative to the 3 UVs that represent the points of the triangle. Like this:

on mFindTexelBaryway me, UV0, UV1, UV2

TexCoord = [] --initialize
TexCoord[1] = ( me.p_vBaryC[1] * UV0.x ) + ( me.p_vBaryC[2] * UV1.x ) + ( 
me.p_vBaryC[3] * UV2.x)
TexCoord[2] = ( me.p_vBaryC[1] * UV0.y ) + ( me.p_vBaryC[2] * UV1.y ) + ( 
me.p_vBaryC[3] * UV2.y)

return TexCoord
end mFindTexelBaryway

Neat! I was so stunned when I got this to work, it was seriously like good 
old-fashioned voodoo. But I can hear you saying 'Why do I want to do all this 
rather than just use the #uvCoord that is returned when I smack into an 
object...' Well, it
depends. Since you are feeding it the 3 UVs associated with the triangle it 
hit, you DON'T have to worry about how the texture is mapped; since the 
texCoords you retrieve from the mesh are the ones that exist when it is already 
projected! And, since
you can get the texture coords from any given texture layer, you can have 
different textures mapped to different layers (with different mapping 
modifiers) and get the (distinct) texture coords for P at any of the different 
layers by a new call to
mFindTexelBaryway.

Is it useful? I'm not totally sure. I used a modification of this as the basis 
for the lightmapper I am working on (I actually go the other way, compute the 
barycentric coords in 2D from texture space and map it to an estimated 3D world 
position) to
'pre-bake' shadows and other rendering artifacts into textures as the movie 
starts up. ( See the screenie!! 
http://andysgi.rit.edu/andyworld10/tests/lightmapper1.jpg )

I hope that it proves useful to you, in your painting applications, but I 
haven't tested it as such, so I don't know if it will meet your needs. If you 
do wind up using it for something really cool I'd appreciate it if you could 
drop me a line and say
'look at the cool thing that incporates that wierd email you wrote to that list 
we can't talk about'. That would make me very happy.

Hope this helps!

-Andy
RIT

Andrew Phelps

Assistant Professor

Department of Information Technology

College of Computing and Information Sciences

Rochester Institute of Technology

http://andysgi.rit.edu  [EMAIL PROTECTED]

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Luiz Gustavo 
Castelan P�voas
Sent: Monday, January 31, 2005 7:34 AM
To: Lingo programming discussion list
Subject: <lingo-l> xy position of a texture


Hello list

I am trying to get the x,y position of the texture applyed to a surface using 
modelUnderLoc,
so, when I click the model, the texture under that mouseloc position gets 
'painted' on the 3d object.

Is it possible with director (I gess so!), how do I get the UV TEXTURE 
position? (instead of UV face
coordinate).



thanks


Luiz


PS: urgent


[To remove yourself from this list, or to change to digest mode, go to 
http://www.penworks.com/lingo-l.cgi  To post messages to the list, email 
[email protected]  (Problems, email [EMAIL PROTECTED]). Lingo-L is for 
learning and helping with programming Lingo.  Thanks!]

[To remove yourself from this list, or to change to digest mode, go to 
http://www.penworks.com/lingo-l.cgi  To post messages to the list, email 
[email protected]  (Problems, email [EMAIL PROTECTED]). Lingo-L is for 
learning and helping with programming Lingo.  Thanks!]

Reply via email to