Here's what I'm trying to do. I have an object that has a regular texture applied. The texture has red and blue parts to it. If my laser hits the red part of the texture I want "this" to happen. If it hits the blue part, I want "that" to happen.
Get the Color of a triangle?
Blitz3D Forums/Blitz3D Programming/Get the Color of a triangle? Look for the pickedu,v code in the archives. Once you have the u & v coords simply get the pixel in question based on u*texturewidth and v * textureheight.
Stevie
Stevie
just use CollisionTriangle, then use TriangleVertex to get one of the triangle's vertices...next just use VertexBlue and VertexRed to return the vertex's color to you.
***EDIT***
If you are using a pick function, then you can use PickedTriangle to get you the triangle's index.
***EDIT***
If you are using a pick function, then you can use PickedTriangle to get you the triangle's index.
Now would the vertex colors correlate to the texture on the triangle? But yes maybe I didn't specify enough. I need to know the texture/brush color of a triangle that was involved in a collision.
Gonna try Stevie's and your methods...brb.
Gonna try Stevie's and your methods...brb.
Ok...what am I doing wrong?
EDIT: Oooh....getting massive MAVs. :(
num = CountCollisions(mesh) surf = CollisionSurface(surf,num) tri = CollisionTriangle(surf,num) red# = VertexRed(???)
EDIT: Oooh....getting massive MAVs. :(
num=CountCollisions(mesh) surf=CollisionSurface(surf,num) tri=PickedTriangle() ; or tri=CollisionTriangle(surf,num) vIndex=TriangleVertex(surf,tri,0) red#=VertexRed(surf,vIndex)
Ok this is working...but it's returning 255s. Which yeah is the vertex color duh lol.
What I need to actually do is return the average color of the triangle texture/brush that was involved in the collision.
EDIT: lol I posted this at the same time you did Kev.
What I need to actually do is return the average color of the triangle texture/brush that was involved in the collision.
EDIT: lol I posted this at the same time you did Kev.
colnum = CountCollisions(b\mesh) surf = CollisionSurface(b\mesh,colnum) tri = CollisionTriangle(b\mesh,colnum) temp = TriangleVertex(surf,tri,0) vert_red = VertexRed(surf,temp) temp = TriangleVertex(surf,tri,1) vert_green = VertexGreen(surf,temp) temp = TriangleVertex(surf,tri,2) vert_blue = VertexBlue(surf,temp)
To get the U/V at that point you can use the VertexU and VertexV...according to Stevie G you then multiply U by TextureWidth and V by TextureHeight...how about trying that.
Ok I just saw the VertexU and VertexV commands.
If I have to do a readpixelfast to do this then I might have to find another method. I hear that has some hefty cost.
If I have to do a readpixelfast to do this then I might have to find another method. I hear that has some hefty cost.
You could also just use GetColor to return the color components at x,y coordinate
Looks like I can just put the texture in a texture buffer, then read the pixel color directly. Pretty sure I got this worked out now...thanks for the input...
EDIT: Yeah I saw that too. We keep hitting enter at the same time. :-)
EDIT: Yeah I saw that too. We keep hitting enter at the same time. :-)
sorry I couldn't help you more...another thing that you could do, though, is use CameraProject on the location of the vertex and then pass ProjectedX and ProjectedY to GetColor
It's too bad that there's not a CollisionU() and CollisionV() command.
Now all I have to do is calculate the actual collision point ON the triangle. Using the texture color of the 3 vertices isn't accurate enough.
Now all I have to do is calculate the actual collision point ON the triangle. Using the texture color of the 3 vertices isn't accurate enough.
If it was me, I'd look for algorithms used for color-picker function in paint programs and see how they do it. Then see if it can be ported/modified for blitz. Good luck on your program!
Maybe it is better to use a pick on the object, because it could be more accurate than a collision. Then you could do a LinePick from the collided object's centerpoint to the collisionobject's centerpoint. Else, you could find the PickedUV from the code vault. I believe it uses PickedTriangle, that can be replaced with CollisionTriangle for your program.
(edit, read kevins reply)
If the collision point in object is in view, you could use GetColor x, y. Or CameraPick camera, x, y.
(edit, read kevins reply)
If the collision point in object is in view, you could use GetColor x, y. Or CameraPick camera, x, y.
I think you're right bram. The easiest way to get accurate uv coords for the collision would be to linepick from the bullet to the center of the object upon collision and record the linepick uv stuff. Thanks man.
Ok...the final solution!
Fredborg's UV linepick code from the archives. Works perfect and was exactly what I was looking for.
Fredborg's UV linepick code from the archives. Works perfect and was exactly what I was looking for.
Ok...the final solution!
Fredborg's UV linepick code from the archives. Works perfect and was exactly what I was looking for.
Which is what Stevie G pointed you to in the very first reply! ;) Fredborg's UV linepick code from the archives. Works perfect and was exactly what I was looking for.
Well you know I like to pursue all avenues and select the best one. kev8084's method seemed easier to implement but I didn't realize it wasn't what I needed.
My thread title was very misleading. Getting the 'color' of a triangle is simple. So I think a couple of people misunderstood ( kev8084). What I was actually looking for was the UV collision coordinates so I could get the texture pixel color at the exact point of impact. That was my bad for not being specific enough.
Ok so I lied. Fred's code wasn't EXACTLY what I was looking for but it's 99% of it. I just need it to work on collision, which isn't hard to implement...so...I'm adapting Fred's PickedUVW code to use collision. Here's what I have so far. It is working but there's a gap where no UVs are ready....it's still WIP.
I'm no math guru myself, but I do understand that you find the triangle that was involved in the collision. Find the 3 vertices and they're coordinates. Then find the exact collision coordinates and plot that on the triangle. Then find the vertice UV coordinates and use that to find the collision point UV coordinates. It just takes me longer to figure that stuff out than Fred. :p
My thread title was very misleading. Getting the 'color' of a triangle is simple. So I think a couple of people misunderstood ( kev8084). What I was actually looking for was the UV collision coordinates so I could get the texture pixel color at the exact point of impact. That was my bad for not being specific enough.
Ok so I lied. Fred's code wasn't EXACTLY what I was looking for but it's 99% of it. I just need it to work on collision, which isn't hard to implement...so...I'm adapting Fred's PickedUVW code to use collision. Here's what I have so far. It is working but there's a gap where no UVs are ready....it's still WIP.
I'm no math guru myself, but I do understand that you find the triangle that was involved in the collision. Find the 3 vertices and they're coordinates. Then find the exact collision coordinates and plot that on the triangle. Then find the vertice UV coordinates and use that to find the collision point UV coordinates. It just takes me longer to figure that stuff out than Fred. :p
; ; CollisionU(), CollisionV(), CollisiondW() commands ; ; Created by Mikkel Fredborg ; ; Adapted to Collision by Chroma (chroma_72@...) ; ; Use as you please, but please include a thank you :) ; Global ent,ind ; ; CollisionTri type ; Necessary for the CollisionU(), CollisionV(), and CollisionW() commands Type CollisionTri Field ent,surf,tri ;picked entity, surface and triangle Field cx#,cy#,cz# ;picked xyz Field cu#[1], cv#[1] ,cw#[1] ;picked uvw x 2 Field vx#[2], vy#[2] ,vz#[2] ;vertex xyz Field vnx#[2], vny#[2] ,vnz#[2] ;vertex normals Field vu#[5], vv#[5] ,vw#[5] ;vertex uvw x 2 End Type Global ctri.CollisionTri = New CollisionTri ; ; Returns the Texture U coordinate of the last successful pick command ; coordset may be set to either 0 or 1 Function CollisionU#(coordset = 0) ; if something new has been picked then calculate the new uvw coordinates If (CollisionX(ent,ind)<>ctri\cx) Or (CollisionY(ent,ind)<>ctri\cy) Or (CollisionZ(ent,ind)<>ctri\cz) Or (CollisionSurface(ent,ind)<>ctri\surf) CollisionUVW() End If Return ctri\cu[coordset] End Function ; ; Returns the Texture U coordinate of the last successful Collision ; coordset may be set to either 0 or 1 Function CollisionV#(coordset = 0) ; if something new has been picked then calculate the new uvw coordinates If (CollisionX(ent,ind)<>ctri\cx) Or (CollisionY(ent,ind)<>ctri\cy) Or (CollisionZ(ent,ind)<>ctri\cz) Or (CollisionSurface(ent,ind)<>ctri\surf) CollisionUVW() End If Return ctri\cv[coordset] End Function ; ; Returns the Texture U coordinate of the last successful pick command ; coordset may be set to either 0 or 1 Function CollisionW#(coordset = 0) ; if something new has been picked then calculate the new uvw coordinates If (CollisionX(ent,ind)<>ctri\cx) Or (CollisionY(ent,ind)<>ctri\cy) Or (CollisionZ(ent,ind)<>ctri\cz) Or (CollisionSurface(ent,ind)<>ctri\surf) CollisionUVW() End If Return ctri\cw[coordset] End Function ; ; Calculates the UVW coordinates of a pick ; Do not call this by yourself, as PickedU(), PickedV(), and PickedW() ; takes care of calling it when nescessary Function CollisionUVW() ;If CollisionSurface(ent,ind) ctri\ent = CollisionEntity(ent,ind);PickedEntity() ctri\surf = CollisionSurface(ent,ind) ctri\tri = CollisionTriangle(ent,ind) ctri\cx = CollisionX(ent,ind) ctri\cy = CollisionY(ent,ind) ctri\cz = CollisionZ(ent,ind) For i = 0 To 2 TFormPoint VertexX(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)),VertexY(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)),VertexZ(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)),ctri\ent,0 ctri\vx[i] = TFormedX() ctri\vy[i] = TFormedY() ctri\vz[i] = TFormedZ() ctri\vnx[i] = VertexNX(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)) ctri\vny[i] = VertexNY(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)) ctri\vnz[i] = VertexNZ(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i)) ctri\vu[i+0] = VertexU(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),0) ctri\vv[i+0] = VertexV(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),0) ctri\vw[i+0] = VertexW(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),0) ctri\vu[i+3] = VertexU(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),1) ctri\vv[i+3] = VertexV(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),1) ctri\vw[i+3] = VertexW(ctri\surf,TriangleVertex(ctri\surf,ctri\tri,i),1) Next ; Select which component of xyz coordinates to ignore Local coords = 3 If Abs(CollisionNX(ent,ind)) > Abs(CollisionNY(ent,ind)) If Abs(CollisionNX(ent,ind))>Abs(CollisionNZ(ent,ind)) Then coords = 1 Else If Abs(CollisionNY(ent,ind))>Abs(CollisionNZ(ent,ind)) Then coords = 2 EndIf Local a0#,a1#,b0#,b1#,c0#,c1# ; xy components If (coords = 3) ; edge 0 a0# = ctri\vx[1] - ctri\vx[0] a1# = ctri\vy[1] - ctri\vy[0] ; edge 1 b0# = ctri\vx[2] - ctri\vx[0] b1# = ctri\vy[2] - ctri\vy[0] ; picked offset from triangle vertex 0 c0# = CollisionX(ent,ind) - ctri\vx[0] c1# = CollisionY(ent,ind) - ctri\vy[0] Else ; xz components If (coords = 2) ; edge 0 a0# = ctri\vx[1] - ctri\vx[0] a1# = ctri\vz[1] - ctri\vz[0] ; edge 1 b0# = ctri\vx[2] - ctri\vx[0] b1# = ctri\vz[2] - ctri\vz[0] ; picked offset from triangle vertex 0 c0# = CollisionX(ent,ind) - ctri\vx[0] c1# = CollisionZ(ent,ind) - ctri\vz[0] Else ; yz components ; edge 0 a0# = ctri\vy[1] - ctri\vy[0] a1# = ctri\vz[1] - ctri\vz[0] ; edge 1 b0# = ctri\vy[2] - ctri\vy[0] b1# = ctri\vz[2] - ctri\vz[0] ; picked offset from triangle vertex 0 c0# = CollisionY(ent,ind) - ctri\vy[0] c1# = CollisionZ(ent,ind) - ctri\vz[0] End If ;End If ; ; u and v are offsets from vertex 0 along edge 0 and edge 1 ; using these it is possible to calculate the Texture UVW coordinates ; of the picked XYZ location ; ; a0*u + b0*v = c0 ; a1*u + b1*v = c1 ; ; solve equation (standard equation with 2 unknown quantities) ; check a math book to see why the following is true ; Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1) Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1) ; If either u or v is out of range then the ; picked entity was not a mesh, and therefore ; the uvw coordinates cannot be calculated If (u<0.0 Or u>1.0) Or (v<0.0 Or v>1.0) Return End If ; Calculate picked uvw's for coordset 0 (and modulate them to be in the range of 0-1 nescessary) ctri\cu[0] = (ctri\vu[0] + ((ctri\vu[1] - ctri\vu[0]) * u) + ((ctri\vu[2] - ctri\vu[0]) * v)) Mod 1 ctri\cv[0] = (ctri\vv[0] + ((ctri\vv[1] - ctri\vv[0]) * u) + ((ctri\vv[2] - ctri\vv[0]) * v)) Mod 1 ctri\cw[0] = (ctri\vw[0] + ((ctri\vw[1] - ctri\vw[0]) * u) + ((ctri\vw[2] - ctri\vw[0]) * v)) Mod 1 ; If any of the coords are negative If ctri\cu[0]<0.0 Then ctri\cu[0] = 1.0 + ctri\cu[0] If ctri\cv[0]<0.0 Then ctri\cv[0] = 1.0 + ctri\cv[0] If ctri\cw[0]<0.0 Then ctri\cw[0] = 1.0 + ctri\cw[0] ; Calculate picked uvw's for coordset 1 (and modulate them to be in the range of 0-1 nescessary) ctri\cu[1] = (ctri\vu[3] + ((ctri\vu[4] - ctri\vu[3]) * u) + ((ctri\vu[5] - ctri\vu[3]) * v)) Mod 1 ctri\cv[1] = (ctri\vv[3] + ((ctri\vv[4] - ctri\vv[3]) * u) + ((ctri\vv[5] - ctri\vv[3]) * v)) Mod 1 ctri\cw[1] = (ctri\vw[3] + ((ctri\vw[4] - ctri\vw[3]) * u) + ((ctri\vw[5] - ctri\vw[3]) * v)) Mod 1 ; If any of the coords are negative If ctri\cu[1]<0.0 Then ctri\cu[1] = 1.0 + ctri\cu[1] If ctri\cv[1]<0.0 Then ctri\cv[1] = 1.0 + ctri\cv[1] If ctri\cw[1]<0.0 Then ctri\cw[1] = 1.0 + ctri\cw[1] End If End Function
@ Big10p, sometimes I feel invisible around here!!
@ Chroma, Why not post the function in the archives to compliment Freds. Code posted in the forums tends to get lost forever.
Stevie
@ Chroma, Why not post the function in the archives to compliment Freds. Code posted in the forums tends to get lost forever.
Stevie
@ Stevie, thanks for pointing me to the archives lol. :p
Nothing should be posted in the archives unless it works 100%. And that function doesn't, so...
For some reason, when the bullet collides with a sphere, there's a dead section on the sphere where no UVs are recorded from CollisionU etc. I'm still investigating.
Nothing should be posted in the archives unless it works 100%. And that function doesn't, so...
For some reason, when the bullet collides with a sphere, there's a dead section on the sphere where no UVs are recorded from CollisionU etc. I'm still investigating.