Advertisement
Bisqwit

Texture coordinate formula generation

Oct 7th, 2015
486
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
QBasic 10.14 KB | None | 0 0
  1. DEFSNG A-Z
  2.  
  3. CONST last = 2
  4. WIDTH 80,50:CLS ' Clear screen
  5.  
  6. TYPE vec3
  7.   x AS SINGLE
  8.   y AS SINGLE
  9.   z AS SINGLE
  10. END TYPE
  11. TYPE vec2
  12.   x AS SINGLE
  13.   y AS SINGLE
  14. END TYPE
  15.  
  16. ' Actual sample data from face 35 in leaf 1039 in sp_a1_intro4.bsp
  17. ' Result we are looking for:
  18. '   u = x*-1.95841 + y*7.48778 + z*-2.02429 + -3826.37
  19. '   v = x*-7.73966 + y*-2.02429 + z*0 + -11783.1
  20. '     X,       Y,       Z,     U,   V
  21. 'DATA -1808,    142.735, 128,   524.0944383000005,    1921.268246849998
  22. 'DATA -1791.87, 144.751, 128,   507.6006494799994,    1792.346562409999
  23. 'DATA -1775.75, 83.2621, 128,   15.61572463800075,    1792.054608590999
  24. 'DATA -1790.86, 77.2148, 128,   -0.07355225599985715, 1921.242360107999
  25.  
  26. '# U formula: u = x*-7.43992 + y*-2.09195 + z*-14.0097 + 14611
  27. '# V formula: u = x*-13.4867 + y*-3.79221 + z*7.72843 + 27058.5
  28. '     X,       Y,       Z,     U,   V
  29. 'DATA 2126.87, -400    , -16  , -151 ,-232
  30. 'DATA 2094.61, -409.067, -16  ,  107 , 236
  31. 'DATA 2094.61, -409.07 , -176 , 2348 ,-999
  32. 'DATA 2126.87, -400    ,-176  , 2089 ,-1469
  33.  
  34. '     X,       Y,       Z,     U,   V
  35. 'DATA 1802227, -1980499, 3734283,   -899,249
  36. 'DATA 2621440, -1966080, 4587520 , -1530,923
  37. 'DATA -2621440, -1966080, 4587520 , 2564,872
  38. 'DATA -1802190, -1980478, 3734276 , 1916,214
  39.  
  40. DATA  4587520 ,   -368640,    -819200 , -352, 551
  41. DATA  4915200  ,  -655360 ,   -778240 , -364, 1890
  42. DATA  4953447 ,   -239506,    -794673 ,  689, 1167
  43.  
  44. ' Read the coordinate data into p() and u().
  45. DIM p(last) AS vec3, uv(last) AS vec2
  46. FOR n = 0 TO last:  READ p(n).x, p(n).y, p(n).z, uv(n).x, uv(n).y: NEXT
  47.  
  48. ' Goal: Determine a,b,c,d such that
  49. '        x*a + y*b + z*c + d  = u
  50.  
  51. DIM pa AS vec3, pb AS vec3, pc AS vec3
  52. DIM SHARED re0 AS vec3, re1 AS vec3, re2 AS vec3
  53.  
  54. ' Convert these three 3D points into 2D points (pa,pb,pc).
  55. ' We also get a matrix in re0,re1,re2.
  56. Flatten p(0),p(1),p(2), pa,pb,pc
  57.  
  58. ' Invert the matrix into qe0,qe1,qe2.
  59. DIM qe0 AS vec3, qe1 AS vec3, qe2 AS vec3
  60. matinv3 re0,re1,re2, qe0,qe1,qe2
  61.  
  62. ' Debug output: Print both matrices.
  63. PRINT "re0:";re0.x;re0.y;re0.z
  64. PRINT "re1:";re1.x;re1.y;re1.z
  65. PRINT "re2:";re2.x;re2.y;re2.z
  66.  
  67. PRINT "qe0:";qe0.x;qe0.y;qe0.z
  68. PRINT "qe1:";qe1.x;qe1.y;qe1.z
  69. PRINT "qe2:";qe2.x;qe2.y;qe2.z
  70.  
  71. ' Debug output: Print the 2D coordinates.
  72. PRINT "---------"
  73. PRINT "pa:";pa.x;pa.y;"(";pa.z;")":PRINT "pb:";pb.x;pb.y;"(";pb.z;")": PRINT "pc:";pc.x;pc.y;"(";pc.z;")":PRINT "---"
  74.  
  75. DIM tmp AS vec3
  76. PRINT "***** FOR U: *******"
  77.  
  78. ' Now that we have 2D points,
  79. ' Solve a,b,c in the following equation:  x*a + y*b + c = u
  80. ' Using the three 2D points.
  81. Solve3vars pa.x,pa.y, pb.x,pb.y, pc.x,pc.y, uv(0).x,uv(1).x,uv(2).x, a,b,c
  82.  
  83. ' Debug output: Test whether the conversion worked.
  84. PRINT "abc:";a;b;c
  85. res = pa.x*a + pa.y*b + c: PRINT "u0: "; res; "expect:";uv(0).x;"error:";ABS(uv(0).x-res)
  86. res = pb.x*a + pb.y*b + c: PRINT "u1: "; res; "expect:";uv(1).x;"error:";ABS(uv(1).x-res)
  87. res = pc.x*a + pc.y*b + c: PRINT "u2: "; res; "expect:";uv(2).x;"error:";ABS(uv(2).x-res)
  88. ' And it did work.
  89.  
  90. ' Now convert the 2D factors (a,b) into 3D by using the inverse matrix.
  91. ' The value of c generated above won't actually be needed for anything.
  92. ' We want x*a + y*b + z*c + d = u. These are a new set of a,b,c,d so we call them aa,bb,cc,dd.
  93. '
  94. tmp.x = a : tmp.y = b: tmp.z = 0 ' z can be anything.
  95. aa = vdot3(tmp, qe0)
  96. bb = vdot3(tmp, qe1)
  97. cc = vdot3(tmp, qe2)
  98. ' We got a,b,c. Solve d by substituting real coordinate data into the equation.
  99. ' It doesn't matter which coordinate we choose for the substitution.
  100. dd = uv(0).x - (p(0).x*aa + p(0).y*bb + p(0).z*cc)
  101. PRINT "aabbccdd:";aa;bb;cc;dd
  102. FOR n = 0 TO last
  103.   res = p(n).x * aa + p(n).y * bb + p(n).z * cc + dd
  104.   PRINT "Got:";res;" expect:";uv(n).x;"error:";ABS(uv(n).x-res)
  105. NEXT
  106.  
  107. PRINT "***** FOR V: *******"
  108.  
  109. Solve3vars pa.x,pa.y, pb.x,pb.y, pc.x,pc.y, uv(0).y,uv(1).y,uv(2).y, a,b,c
  110. PRINT "abc:";a;b;c
  111. res = pa.x*a + pa.y*b + c: PRINT "u0: "; res; "expect:";uv(0).y;"error:";ABS(uv(0).y-res)
  112. res = pb.x*a + pb.y*b + c: PRINT "u1: "; res; "expect:";uv(1).y;"error:";ABS(uv(1).y-res)
  113. res = pc.x*a + pc.y*b + c: PRINT "u2: "; res; "expect:";uv(2).y;"error:";ABS(uv(2).y-res)
  114.  
  115. tmp.x = a : tmp.y = b: tmp.z = 0 ' z can be anything.
  116. aa = vdot3(tmp, qe0)
  117. bb = vdot3(tmp, qe1)
  118. cc = vdot3(tmp, qe2)
  119. dd = uv(0).y - (p(0).x*aa + p(0).y*bb + p(0).z*cc)
  120. PRINT "aabbccdd:";aa;bb;cc;dd
  121. FOR n = 0 TO last
  122.   res = p(n).x * aa + p(n).y * bb + p(n).z * cc + dd
  123.   PRINT "Got:";res;" expect:";uv(n).y;"error:";ABS(uv(n).y-res)
  124. NEXT
  125.  
  126. END
  127.  
  128.  
  129.  
  130. SUB vadd2(a AS vec2, b AS vec2, result AS vec2)
  131.   result.x = a.x + b.x
  132.   result.y = a.y + b.y
  133. END SUB
  134. SUB vsub2(a AS vec2, b AS vec2, result AS vec2)
  135.   result.x = a.x - b.x
  136.   result.y = a.y - b.y
  137. END SUB
  138. SUB vmul2(a AS vec2, b AS vec2, result AS vec2)
  139.   result.x = a.x * b.x
  140.   result.y = a.y * b.y
  141. END SUB
  142. SUB vmul2s(a AS vec2, b, result AS vec2)
  143.   result.x = a.x * b
  144.   result.y = a.y * b
  145. END SUB
  146. SUB vdiv2(a AS vec2, b AS vec2, result AS vec2)
  147.   result.x = a.x / b.x
  148.   result.y = a.y / b.y
  149. END SUB
  150. FUNCTION vdot2(a AS vec2, b AS vec2)
  151.   vdot2 = a.x * b.x + a.y * b.y
  152. END SUB
  153. FUNCTION vlen2(a AS vec2)
  154.   vlen2 = SQR(vdot2(a,a))
  155. END SUB
  156. SUB vnorm2(a AS vec2, result AS vec2)
  157.   l = vlen2(a)
  158.   result.x = a.x / l
  159.   result.y = a.y / l
  160. END SUB
  161. FUNCTION vxs2(a AS vec2, b AS vec2)
  162.   vxs2 = a.x*b.y - a.y*b.x
  163. END FUNCTION
  164.  
  165. SUB vadd3(a AS vec3, b AS vec3, result AS vec3)
  166.   result.x = a.x + b.x
  167.   result.y = a.y + b.y
  168.   result.z = a.z + b.z
  169. END SUB
  170. SUB vsub3(a AS vec3, b AS vec3, result AS vec3)
  171.   result.x = a.x - b.x
  172.   result.y = a.y - b.y
  173.   result.z = a.z - b.z
  174. END SUB
  175. SUB vmul3(a AS vec3, b AS vec3, result AS vec3)
  176.   result.x = a.x * b.x
  177.   result.y = a.y * b.y
  178.   result.z = a.z * b.z
  179. END SUB
  180. SUB vmul3s(a AS vec3, b, result AS vec3)
  181.   result.x = a.x * b
  182.   result.y = a.y * b
  183.   result.z = a.z * b
  184. END SUB
  185. SUB vdiv3(a AS vec3, b AS vec3, result AS vec3)
  186.   result.x = a.x / b.x
  187.   result.y = a.y / b.y
  188.   result.z = a.z / b.z
  189. END SUB
  190. FUNCTION vdot3(a AS vec3, b AS vec3)
  191.   vdot3 = a.x * b.x + a.y * b.y + a.z * b.z
  192. END SUB
  193. FUNCTION vlen3(a AS vec3)
  194.   vlen3 = SQR(vdot3(a,a))
  195. END SUB
  196. SUB vnorm3(a AS vec3, result AS vec3)
  197.   l = vlen3(a)
  198.   result.x = a.x / l
  199.   result.y = a.y / l
  200.   result.z = a.z / l
  201. END SUB
  202. SUB vxs3(a AS vec3, b AS vec3, result AS vec3)
  203.   DIM temp AS vec2
  204.   temp.x = a.y*b.z - a.z*b.y
  205.   temp.y = a.z*b.x - a.x*b.z
  206.   result.z = a.x*b.y - a.y*b.x
  207.   result.x = temp.x
  208.   result.y = temp.y
  209. END SUB
  210. SUB matmul3(m0 AS vec3,m1 AS vec3,m2 AS vec3, n0 AS vec3,n1 AS vec3,n2 AS vec3, r0 AS vec3,r1 AS vec3,r2 AS vec3)
  211.   r0.x = m0.z*n2.x + m0.y*n1.x + m0.x*n0.x
  212.   r0.y = m0.z*n2.y + m0.y*n1.y + m0.x*n0.y
  213.   r0.z = m0.z*n2.z + m0.y*n1.z + m0.x*n0.z
  214.   r1.x = m1.z*n2.x + m1.y*n1.x + m1.x*n0.x
  215.   r1.y = m1.z*n2.y + m1.y*n1.y + m1.x*n0.y
  216.   r1.z = m1.z*n2.z + m1.y*n1.z + m1.x*n0.z
  217.   r2.x = m2.z*n2.x + m2.y*n1.x + m2.x*n0.x
  218.   r2.y = m2.z*n2.y + m2.y*n1.y + m2.x*n0.y
  219.   r2.z = m2.z*n2.z + m2.y*n1.z + m2.x*n0.z
  220. END SUB
  221. SUB matinv3(m0 AS vec3,m1 AS vec3,m2 AS vec3, r0 AS vec3,r1 AS vec3,r2 AS vec3)
  222.   DIM tmp AS vec3
  223.   vxs3 m1,m2, tmp: invdet = 1! / vdot3(m0, tmp)
  224.   PRINT "matinv3: det=";det
  225.   vxs3 m1,m2, tmp: r0.x = tmp.x * invdet: r1.x = tmp.y * invdet: r2.x = tmp.z * invdet
  226.   vxs3 m2,m0, tmp: r0.y = tmp.x * invdet: r1.y = tmp.y * invdet: r2.y = tmp.z * invdet
  227.   vxs3 m0,m1, tmp: r0.z = tmp.x * invdet: r1.z = tmp.y * invdet: r2.z = tmp.z * invdet
  228. END SUB
  229.  
  230. SUB Flatten(a AS vec3, b AS vec3, c AS vec3, out1 AS vec3,out2 AS vec3,out3 AS vec3)
  231.   DIM ba AS vec3, ca AS vec3, normal AS vec3
  232.   DIM vX1 AS vec3, vX2 AS vec3
  233.   DIM vZ1 AS vec3, vZ2 AS vec3, vY AS vec3
  234.   DIM m0 AS vec3, m1 AS vec3, m2 AS vec3
  235.   vsub3  b,a, ba
  236.   vsub3  c,a, ca
  237.   vxs3   ba, ca, normal
  238.   vnorm3 normal, vX2
  239.   vX1.x = 0: vX1.y = 0: vX1.z = 1
  240.   vxs3 vX1, vX2, vY
  241.   'PRINT "vX2 (normal):"; vX2.x;vX2.y;vX2.z
  242.   'PRINT "vY:"; vY.x;vY.y;vY.z
  243.   IF vdot3(vY,vY) > 0 THEN
  244.     vnorm3 vY, vY
  245.     vxs3 vX1, vY, vZ1 : vnorm3 vZ1, vZ1
  246.     vxs3 vX2, vY, vZ2 : vnorm3 vZ2, vZ2
  247.     'PRINT "vZ1:"; vZ1.x;vZ1.y;vZ1.z
  248.     'PRINT "vZ2:"; vZ2.x;vZ2.y;vZ2.z
  249.     m0.x = vX1.x: m0.y = vY.x: m0.z = vZ1.x
  250.     m1.x = vX1.y: m1.y = vY.y: m1.z = vZ1.y
  251.     m2.x = vX1.z: m2.y = vY.z: m2.z = vZ1.z
  252.     matmul3 m0,m1,m2, vX2,vY,vZ2, re0,re1,re2
  253.   ELSE
  254.     re0.x = 1 : re0.y = 0: re0.z = 0
  255.     re1.x = 0 : re1.y = 1: re1.z = 0
  256.     re2.x = 0 : re2.y = 0: re2.z = 1
  257.   END IF
  258.   out1.x = vdot3(a,re0)
  259.   out1.y = vdot3(a,re1)
  260.   out1.z = vdot3(a,re2)
  261.   out2.x = vdot3(b,re0)
  262.   out2.y = vdot3(b,re1)
  263.   out2.z = vdot3(b,re2)
  264.   out3.x = vdot3(c,re0)
  265.   out3.y = vdot3(c,re1)
  266.   out3.z = vdot3(c,re2)
  267. END SUB
  268.  
  269. SUB Solve3vars(x1,y1, x2,y2, x3,y3, u1,u2,u3, a,b,c)
  270.   det = (y1*(x3-x2) + y2*(x1-x3) + y3*(x2-x1))
  271.   invdet = 1! / det
  272.   PRINT "Solve3: det=";det
  273.   a   = (y1*(u3-u2) + y2*(u1-u3) + y3*(u2-u1)) * invdet
  274.   b   = (x1*(u3-u2) + x2*(u1-u3) + x3*(u2-u1)) * -invdet
  275.   c   = (y1*(u2*x3-u3*x2) + y2*(u3*x1-u1*x3) + y3*(u1*x2-u2*x1)) * invdet
  276. END SUB
  277.  
  278. ' Solve4vars is unused.
  279. SUB Solve4vars(x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, u1,u2,u3,u4, a,b,c,d)
  280.   ' ratsimp(solve( [x1*a+y1*b+z1*c+d=u1,x2*a+y2*b+z2*c+d=u2,x3*a+y3*b+z3*c+d=u3,x4*a+y4*b+z4*c+d=u4], [a,b,c,d] ))
  281.   det =(z4*((x2-x1)*y3+(x1-x3)*y2+(x3-x2)*y1) _
  282.        +z3*((x1-x2)*y4+(x2-x4)*y1+(x4-x1)*y2) _
  283.        +z2*((x4-x3)*y1+(x3-x1)*y4+(x1-x4)*y3) _
  284.        +z1*((x3-x4)*y2+(x4-x2)*y3+(x2-x3)*y4))
  285.   a = (z4*(y3*(u2-u1)+y2*(u1-u3)+y1*(u3-u2)) _
  286.       +z3*(y4*(u1-u2)+y2*(u4-u1)+y1*(u2-u4)) _
  287.       +z2*(y4*(u3-u1)+y3*(u1-u4)+y1*(u4-u3)) _
  288.       +z1*(y4*(u2-u3)+y3*(u4-u2)+y2*(u3-u4))) / det
  289.   b = (z4*(x3*(u2-u1)+x2*(u1-u3)+x1*(u3-u2)) _
  290.       +z3*(x4*(u1-u2)+x2*(u4-u1)+x1*(u2-u4)) _
  291.       +z2*(x4*(u3-u1)+x3*(u1-u4)+x1*(u4-u3)) _
  292.       +z1*(x4*(u2-u3)+x3*(u4-u2)+x2*(u3-u4))) / -det
  293.   c = (y4*(x3*(u2-u1)+x2*(u1-u3)+x1*(u3-u2)) _
  294.       +y3*(x4*(u1-u2)+x2*(u4-u1)+x1*(u2-u4)) _
  295.       +y2*(x4*(u3-u1)+x3*(u1-u4)+x1*(u4-u3)) _
  296.       +y1*(x4*(u2-u3)+x3*(u4-u2)+x2*(u3-u4))) / det
  297.   d = (z4*(y3*(u1*x2-u2*x1)+y2*(u3*x1-u1*x3)+y1*(u2*x3-u3*x2)) _
  298.       +z3*(y4*(u2*x1-u1*x2)+y2*(u1*x4-u4*x1)+y1*(u4*x2-u2*x4)) _
  299.       +z2*(y4*(u1*x3-u3*x1)+y3*(u4*x1-u1*x4)+y1*(u3*x4-u4*x3)) _
  300.       +z1*(y4*(u3*x2-u2*x3)+y3*(u2*x4-u4*x2)+y2*(u4*x3-u3*x4))) / det
  301. END SUB
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement