|
Well its been a long time and TBH i cannot remember how you texture models anymore. The person who taught me was Mr. Potatohead if anyone remembers him I hope so because he created the DAT Maker. Well he seems to pop up every once in awhile and someone reached out to me about texturing models and after scanning the archive of the web I found a post he poped up on which has a unreleased version of the dat maker. Turns out my friend who had reached out for help had downloaded this file before it expired (idk what the odds of this were) Anyways he sent it to me and we found this text file on the inside.
This file explain everything about texturing if someone has the time PLEASE refigure out how it was once done. I wish i remember how I did it and I wish my old posts & sites explaining how to do it still existed but they don't.
Here is an example of some of the models I made (Mr.P did the first half of the wings)
[SPOIL]
Aim
To find the 3D triangle that runescape clients use to draw textures onto model parts.
In the client a texture is not stored as UV coordinates.
Instead a 3D triangle is used to determine the area to be filled with pixels from the image.
The triangle represents a square plane of the entire texture.
Try to think of the 'texture triangle' as a square area.
You only really need to know the top corner and the length and width to draw the entire texture as a square area.
Your 3D model triangle that the texture is linked to is like a triangular fill mask to say which bits to draw and which to not.
At the lowest level a UV coordinate is ultimately converted to a 2D drawing area on the screen, jagex just removed the need to do the maths client side.
Remember it's before openGL became popular on all platforms.
We are now left needing to do exactly the same thing as jagex and strip out all the UV info and just leave a texture fill area represented by a 3D triangle.
So how do we determine the 3D corner points of a texture, UV(0,0), UV(0,1), UV(1,0), UV(1,1) given only UV coordinates from metasequoia?
MATHS!!!!!! Aaaargh!!!!
It's really simple.
We use matrices found on the roswell spacecraft.
A very clever person on gamesdev came up with this, so don't blame me if don't understand it, it works so we use it.
You don't need to understand what's happening, it's there to show you how to get to the final equations.
There are other methods of doing it and different ways of doing the maths so don't get confused if you see it done another way.
Form the matrices
[u1 u2 u3]
[v1 v2 v3] = UVw 3 UV coords of 3 points in a triangle
[ 1 1 1]
and
[x1 x2 x3]
[y1 y2 y3] = XYZ 3 points of the triangle
[z1 z2 z3]
point 1 uses x1,y1,z1 and has a UV coordinate of U1,V1
Then the 3D point corresponding to a particular UV is given by XYZ * inverse(U) * vec3(u,v,1).
For example:- XYZ * inverse(U) * vec3(1,1,1) is the point corresponding to a UV of (1,1) (one of the corners we need!!!)
Simple? LOL - we need an inverse matrix of U
To get an inverse matrix we need to find the determinate and the adjoint matrices.
AND to get the adjoint, we need to find the cofactor matrix.
Aren't matrices fun
Finding the determinate is very easy.
_matrix
j k l
m n o determinant = (jnr+kop+lmq)-(lnp+kmr+joq)
p q r
Told you it was easy
Now for the adjoint.
The adjoint is a transposed cofactor matrix.
The cofactor matrix is made from finding the minors of the matrix.
For an example we will use a matrix A
Matrix A
A11=j a12=k a13=l
A21=m a22=n a23=o
A31=p a32=q a33=r
We re-label them for clarity
Step 1: Calculate Minor for each element, the minor labeled M, the middle column shows how to work out the minor from matrix A
The right column shows it re-label back to the original _matrix.
M11 = a22 x a33 - a32 x a23 = (n*r)-(q*o)
M12 = a21 x a33 - a31 x a23 = (m*r)-(p*o)
M13 = a21 x a32 - a31 x a22 = (m*q)-(p*n)
M21 = a12 x a33 - a32 x a13 = (k*r)-(q*l)
M22 = a11 x a33 - a31 x a13 = (j*r)-(p*l)
M23 = a11 x a32 - a31 x a12 = (j*q)-(p*k)
M31 = a12 x a23 - a22 x a13 = (k*o)-(n*l)
M32 = a11 x a23 - a21 x a13 = (j*o)-(m*l)
M33 = a11 x a22 - a21 x a12 = (j*n)-(m*k)
So the cofactor matrix is simple, we write the minors in matrix form.
cofactor matrix
(n*r)-(q*o) (m*r)-(p*o) (m*q)-(p*n)
(k*r)-(q*l) (j*r)-(p*l) (j*q)-(p*k)
(k*o)-(n*l) (j*o)-(m*l) (j*n)-(m*k)
The adjoint is a transposed cofactor matrix, meaning we just rearrange it.
adjoint matrix
(n*r)-(q*o) (k*r)-(q*l) (k*o)-(n*l)
(m*r)-(p*o) (j*r)-(p*l) (j*o)-(m*l)
(m*q)-(p*n) (j*q)-(p*k) (j*n)-(m*k)
so if the cofactor was
a b c
d e f
g h i
the adjoint is
a d g
b e h
c f i
Now finding the inverse of a matrix nowe that we have the determinate and adjoint.
1
inverse = ---------- * adjoint
determinate
Now we have to fill that in with the matrices.
from matrix
[u1 u2 u3]
[v1 v2 v3]
[ 1 1 1]
rewrite as
[ jkl ]
[ mno ]
[ pqr ]
1 |-(o) (k)-(l) (k*o)-(n*l)|
inverse = (j*n+k*o+l*m)-(l*n+k*m+j*o) * |(m)-(o) (j)-(l) (j*o)-(m*l)|
|(m)- (j)-(k) (j*n)-(m*k)|
Now multiply it all out.............
-(o) (k)-(l) (k*o)-(n*l)
(j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o)
(m)-(o) (j)-(l) (j*o)-(m*l)
(j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o)
(m)- (j)-(k) (j*n)-(m*k)
(j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o) (j*n+k*o+l*m)-(l*n+k*m+j*o)
and now rewrite it back to the original form...........
(v2)-(v3) (u2)-(u3) (u2*v3)-(v2*u3)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
(v1)-(v3) (u1)-(u3) (u1*v3)-(v1*u3)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
(v1)-(v2) (u1)-(u2) (u1*v2)-(v1*u2)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3) (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
Is that it?
Well we only really found the inverse of a matrix and completely forgot why we needed it.
We needed it for the original equation.
XYZ * inverse(UVw) * vec3(u,v,1).
XYZ is the x,y,z points in the triangle
UVw is the UV coordinates of the 3 points
vec3 is the UVw point we want to find the x,y,z position of.
So we know how to get the inverse of a matrix from earlier.
1 |(n*r)-(q*o) (k*r)-(q*l) (k*o)-(n*l)|
inverse = (j*n*r+k*o*p+l*m*q)-(l*n*p+k*m*r+j*o*q) * |(m*r)-(p*o) (j*r)-(p*l) (j*o)-(m*l)|
of UVw |(m*q)-(p*n) (j*q)-(p*k) (j*n)-(m*k)|
And we rewrite the matrix layout to make sense.
[x1 x2 x3] |inverse| |1| |x|
[y1 y2 y3] * | of |*|1| = |y|
[z1 z2 z3] | UVw | |1| |z|
3 points * inverse * the UV corner we want to find = the 3D position of the UV(1,1) corner of the texture.
of UVw
Now lets simplify the equations down a bit by multiplying the matrix [inverse of UVw] by the matrix [UV(1,1,1)]
[ jkl ] |1| |p|
[ mno ] * |1| = |q|
[ pqr ] |1| |r|
becomes.....
p = (n-o) (k)-(l) (k*o)-(n*l)
((j*n+k*o+l*m)-(l*n+k*m+j*o)) + (j*n+k*o+l*m)-(l*n+k*m+j*o) + (j*n+k*o+l*m)-(l*n+k*m+j*o)
rewritten.....
p = ((n-o)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + ((k-l)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + (((k*o)-(n*l))/((j*n+k*o+l*m)-(l*n+k*m+j*o)))
simplyfied......
p = (k - l + n - l*n + (-1 + k)*o)
(l*(m - n) + j*(n - o) + k*(-m + o))
So that's the result for p
q = ((m-o)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + ((j-l)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + (((j*o)-(m*l))/((j*n+k*o+l*m)-(l*n+k*m+j*o)))
simplyfied..............
q = (l - m + l*m + o - j*(1 + o))
(l*(-m + n) + k*(m - o) + j*(-n + o))
r = ((m-n)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + ((j-k)/((j*n+k*o+l*m)-(l*n+k*m+j*o))) + (((j*n)-(m*k))/((j*n+k*o+l*m)-(l*n+k*m+j*o)))
simplyfied.....
r = (j - k + m - k*m + (-1 + j)*n)
(l*(m - n) + j*(n - o) + k*(-m + o))
we don't really need to write the matix out for
|p|
|q|
|r|
because we are multiplying it with the XYZ matrix.
[x1 x2 x3] |p|
[y1 y2 y3] *|q|
[z1 z2 z3] |r|
So our final step is to do that.
x1*p + x2*q + x3*r = x value for UV(1,1)
y1*p + y2*q + y3*r = y value for UV(1,1)
z1*p + z2*q + z3*r = z value for UV(1,1)
Which become our general equations for the corners of the texture.
X = x1*p + x2*q + x3*r
Y = y1*p + y2*q + y3*r
Z = z1*p + z2*q + z3*r
since we only change the vec3(u,v,1) we just need to work out the pqr matrix for each of the four corners UV(0,0), UV(0,1), UV(1,0), UV(1,1)
----------------------------------------------
FOR UV(1,1)
p = (u2 - u3 + v2 - u3*v2 + (-1 + u2)*v3)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
q = (u1 - u3 + v1 - u3*v1 + (-1 + u1)*v3)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
r = (u1 - u2 + v1 - u2*v1 + (-1 + u1)*v2)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
----------------------------------------------
FOR UV(0,0)
p = (u2*v3)-(v2*u3)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
q = (u1*v3)-(v1*u3)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
r = (u1*v2)-(v1*u2)
(u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
----------------------------------------------
FOR UV(0,1)
p = (-(u3*(1 + v2)) + u2*(1 + v3))
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
q = (-(u3*(1 + v1)) + u1*(1 + v3))
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
r = (-(u2*(1 + v1)) + u1*(1 + v2))
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
----------------------------------------------
FOR UV(1,0)
p = (v2 - u3*v2 + (-1 + u2)*v3)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
q = (v1 - u3*v1 + (-1 + u1)*v3)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
r = (v1 - u2*v1 + (-1 + u1)*v2)
(u3*(v1 - v2) + u1*(v2 - v3) + u2*(-v1 + v3))
----------------------------------------------
How do we write a program to do that?
Given 3 points
x1,y1,z1,x2,y2,z2,x3,y3,z3
each with their own UV coordinate
u1,v1,u2,v2,u3,v3
****for UV(1,1)****
p = (u2-u3+v2-u3*v2+(-1+u2)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (u1-u3+v1-u3*v1+(-1+u1)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (u1-u2+v1-u2*v1+(-1+u1)*v2) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
****for UV(0,0)****
p = (u2*v3)-(v2*u3) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
q = (u1*v3)-(v1*u3) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
r = (u1*v2)-(v1*u2) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
****for UV(0,1)****
p = (-(u3*(1+v2))+u2*(1+v3)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (-(u3*(1+v1))+u1*(1+v3)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (-(u2*(1+v1))+u1*(1+v2)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
****for UV(1,0)****
p = (v2-u3*v2+(-1+u2)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (v1-u3*v1+(-1+u1)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (v1-u2*v1+(-1+u1)*v2) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
-----------------------------------------------------------
As you can see the equations to the rights of the divisions are the same.
No need to calculate stuff twice....
you have the general equations for x,y,z
X = x1*p + x2*q + x3*r
Y = y1*p + y2*q + y3*r
Z = z1*p + z2*q + z3*r
which means you should be able to write a quick program to get the 3D coordinates of the corners of a texture from ANY 3D triangle with
UV texture coordinates.
First try a simple program to convert all textured triangles into texture triangles, manually remove any superfluous texture triangles,
use datmaker and a hex editor to manually create a simple textured model that loads into the client.
Then try making the program do it all in one go, adding capability one step at a time.
Things to consider.................
Which 3 out of the 4 corners does the client require?
And in what order?
UV(0,0), UV(0,1) and UV(1,0) if I remember correctly.
A texture triangle can link to and cover more than 1 3D model triangle, so if the corners for each 3D model texture are the same, they will have
the same texture triangle. You need to check for this. And compensate for computational mathematical errors.
You only have 64 texture triangles, use them wisely.
A square 3D model with a texture mapped to it's faces will obviously already have UV coordinates which are the same as the corners, you don't
need to do any maths for these, just check for them.
Does/can the client use repeat on the texures? ie will it tile them if the texture triangle is smaller than the 3D mapping triangle?
Can animated textures be used on any model?
Dragonking has a set of dragon lava wings for a cape, using lava textures. (I know because I made the texture triangles for them.)
Lava/water trees?
Lava/water/magic monsters?
Start simple, make a portrait of bert for lumbridge castle, requires a new texture, 2 model triangles and 1 texture triangle, plus of course the correct
material and texture triangle data, don't forget the texture flag.
How do you actually tell the client which texture to use? colours 0 to 50 in the COLOR_DATA_Chunk
File format specification for old format (pre 474)
-----------------------------------------------------------------------
VERTEX_DIRECTION_Chunk : Bytes; Number of verices in length.
This chunk contains Vertex direction data, the data contained in each byte is a set Bit of Flags. Only the first 3 bits are used.
Each Flag determines whether an addition is made to the x,y, or z axis when calculating the next vertex point.
Example: The start point is always 0,0,0, so if the first vertex is at point 10,10,10 then the All the Flags will be set and the byte value = 7.
ALWAYS Required.
-----------------------------------------------------------------------
TRIANGLE_TYPE_Chunk : Bytes; Number of triangles in length.
This chunk contains Triangle type data, the data is an integer Flag, of value 1-4, used to control how Triangles vertex numbers are loaded.
Type_1 = New Triangle. Load v1, v2 and v3.
Type_2 = v2=v3, load v3, v1=v1
Type_3 = v1=v3, load v3, v2=v2
Type_4 = v1=v2, v2=v1, load v3
NOTE: Type_4 is rare, Type_1 can be used to replace type 4 with only a small loss in compression.
Type_4 can only exist in 2 instances,
a) when a new triangle is loaded and the next triangle type is of type_4.
b) when the normal of the next triangle is inverted.
Otherwise the vast majority of triangles will be of type_2 and type_3
ALWAYS Required.
-----------------------------------------------------------------------
TRIANGLE_PRIORITY_Chunk : Bytes; Number of triangles in length.
This chunk contains integer values used to calculate which triangles are drawn first, The higher the value the later they are drawn.
Used only when triangle priority is required.
-----------------------------------------------------------------------
TRIANGLE_SKIN_Chunk : Bytes; Number of triangles in length.
This chunk contains integer values that are applied to triangles in order to display animation data. The value represents the group the triangle belongs to.
Used only when animation is required.
-----------------------------------------------------------------------
TEXTURE_POINTER_Chunk : Bytes; Number of triangles in length.
This chunk contains integer values that point to which texture mapping triangle is used to texture the model triangle.
A Value of 0 represents NO texture mapping.
Used only when texture mapping is required.
-----------------------------------------------------------------------
VERTEX_SKIN : Bytes; Number of vertices in length.
This chumck contains integer values that describe which vertex skin group a vertex belongs to.
Used only when animation is required.
-----------------------------------------------------------------------
TRIANGLE_ALPHA_Chunk : Bytes; Number of Triangles in length
This chunk conatins integer values that are used to determine how transparent the model triangle is.
Used only when transparency is required.
-----------------------------------------------------------------------
TRIANGLE_DATA_CHUNK : Bytes and/or Words; Length is Triangle_Data Length.
This chunk contains signed bytes and words that are used to calculate which vertices are used to describe the triangle. The value has an offset of 64 to determine wether the value is stored as a byte or a word. A base value of 0 is used. The values are stored as offsets to the next vertex.
Example: the model starts with a triangle that uses vertices 2,3,4.
The offsets from the base value will be +2,+1,+1
This will be stored as 66,65,65 (or in Hex 42,41,41)
ALWAYS Required.
-----------------------------------------------------------------------
COLOR_DATA_Chunk : Words; Number of triangles in length.
This chunk contains integer values that describe which color, from the 65,536 color lookuptable, is used for the model triangle.
ALWAYS Required.
-----------------------------------------------------------------------
UV_MAP_TRIANGLES_Chunk : Word,Word,Word; Number of texture triangles in length.
This chunk contains the positions of the UV(0,0), UV(0,1) and UV(1,0) information required to calculate the UV coordinates for textured model triangles. The 'texture triangle' represents the flat mapped texture which the model triangles are projected onto to produce the UV coordinates.
Used only when texture mapping is required.
-----------------------------------------------------------------------
X_DATA_Chunk : Byte and/or Word; XdataLength in length
This chunk contains signed bytes or words, used to calculate the X value for the vertex position. A base offset of 0 is used and the number stored is the offset from one vertex position to the next.
An offset of 64 is also applied to the data to determine if the value is stored as a byte or a word.
ALWAYS Required.
-----------------------------------------------------------------------
Y_DATA_Chunk : Byte and/or Word; YdataLength in length
This chunk contains signed bytes or words, used to calculate the Y value for the vertex position. A base offset of 0 is used and the number stored is the offset from one vertex position to the next.
An offset of 64 is also applied to the data to determine if the value is stored as a byte or a word.
ALWAYS Required.
-----------------------------------------------------------------------
Z_DATA_Chunk : Byte and/or Word; ZdataLength in length
This chunk contains signed bytes or words, used to calculate the Z value for the vertex position. A base offset of 0 is used and the number stored is the offset from one vertex position to the next.
An offset of 64 is also applied to the data to determine if the value is stored as a byte or a word.
ALWAYS Required.
-----------------------------------------------------------------------
FILE_FOOTER_Chunk : Bytes and Words; Length is 18 bytes.
This chunk contains the data lengths and data flags used to store the file.
Word - Number of vertices
Word - Number of triangles
Byte - Number of Texture triangles
Byte - Use textures FLAG
Byte - Use Triangle Priorities FLAG (FF for True)
Byte - Use Transparency FLAG
Byte - Use Triangle Skinning FLAG
Byte - Use Vertex Skinning FLAG
Word - X_DATA length
Word - Y_DATA length
Word - Z_DATA length
Word - Triangle_Data length
ALWAYS Required.
-----------------------------------------------------------------------
[/SPOIL]
well texturing models for a 317 can be done but hats new is texturing models for 667+ the 667 version is in hex idk the 317 what does it read but im pretty sure u can figure it out back if u done something once u can do it again.
I have it mostly figured out, I can apply textures to triangles but am still working out a few kinks with the UV calculation for controlling how it's drawn.
Heres a very simple model I just made, we will apply texture to the red faces:
Step 1) Open model .dat file in hex editor
Separate the last 18 bytes from the rest and organize them. This is the model "header" which is actually a "footer" as it comes end of file.Code:0702 0302 0401 0103 0103 0202 0000 433f 3f3f 4441 3e3e 000e 000e a7bf a7bf 0000 0002 0003 16c0 54bf acbf 4bc0 afbf 51c0 af3a c054 0006 0004 0000 0000 0000 0005 0008 0003 0008
Code:0006 //WORD - Vertex count 0004 //WORD - Triangle count 00 //BYTE - Texture mapping triangle count 00 //BYTE - Use textures flag (00 = false, 01+ = true) 00 //BYTE - Use priorities flag 00 //BYTE - Use alpha flag 00 //BYTE - Use triangle skinning flag 00 //BYTE - Use vertex skinning flag 0005 0008 0003 //3x WORDs - XDATA,YDATA,ZDATA lengths 0008 //WORD - TRIANGLE_DATA length
So we know that this model has 6 vertices and 4 triangles.
With that in mind, we can sort the model file into chunks
using the model format documentation as reference.
Now, change 2 values in the FILE_FOOTER_Chunk. "Use textures flag" from FALSE(00) to TRUE(01);Code://VERTEX_DIRECTION_Chunk 07 02 03 02 04 01 //TRIANGLE_TYPE_Chunk 01 03 01 03 //TRIANGLE_DATA_CHUNK 433f 3f3f 4441 3e3e //COLOR_DATA_Chunk f7bf f7bf a7bf a7bf //X,Y,Z, DATA_Chunks 16c0 54bf acbf 4bc0 afbf 51c0 af3a c054 //FILE_FOOTER_Chunk 0006 0004 00 00 00 00 00 00 0005 0008 0000 0008
also set the "Texture mapping triangle count", from 00 to 01.
So now that textures are enabled in the model, when the model loads it expect two additional data chunks:
"TEXTURE_POINTER_Chunk"
directly after TRIANGLE_TYPE_Chunk. We add 4 00 bytes, one for each triangle,TEXTURE_POINTER_Chunk : Bytes; Number of triangles in length.
This chunk contains integer values that point to which texture mapping triangle is used to texture the model triangle.
A Value of 0 represents NO texture mapping.
Used only when texture mapping is required.
and change the 00s to 02s for the triangles we want textured.
Code:01 03 01 03 02 02 00 00
Next we have to add "UV_MAP_TRIANGLES_Chunk"
directly after the COLOR_DATA_Chunk.UV_MAP_TRIANGLES_Chunk : Word,Word,Word; Number of texture triangles in length.
This chunk contains the positions of the UV(0,0), UV(0,1) and UV(1,0) information required to calculate the UV coordinates for textured model triangles. The 'texture triangle' represents the flat mapped texture which the model triangles are projected onto to produce the UV coordinates.
Used only when texture mapping is required.
For each texture mapping triangle, we add 3 WORDs.
(* see bottom note for info on calculating the values)Code:f7bf f7bf a7bf a7bf 0000 0002 0003
At this point the model file has everything it needs.
The texture ID to use for the textured triangles are determined by that triangle's color value in the COLOR_DATA_Chunk.
Change the original HSL color value to the texture ID, for each triangle we textured. In the cache, lava is 40 so in hex: 28
becomesCode:f7bf f7bf a7bf a7bf
And voila; textured trianglesCode:0028 0028 a7bf a7bf
Finished file for reference:
Code:07 02 03 02 04 01 01 03 01 03 02 02 00 00 433f 3f3f 4441 3e3e 0028 0028 a7bf a7bf 0000 0002 0003 16c0 54bf acbf 4bc0 afbf 51c0 af3a c054 0006 0004 01 01 00 00 00 00 0005 0008 0003 0008
___
Now, what I don't fully understand is the calculation of the 3 WORDs in UV_MAP_TRIANGLES_Chunk.
points which describe the corner positions of the "texture mapping triangle"contains the positions of the UV(0,0), UV(0,1) and UV(1,0) information required to calculate the UV coordinates for textured model triangles.
In this tutorial I used the values: 0000 0002 0003. I got them by turning on "Vert nums" in Datamaker and choosing the 3 corner vertices of the plane I wanted textured.
It looks ok in this instance, but it is not correct.
The note file you quoted in OP describes the proper way to calculate the values given 3x (X,Y,Z,U1,U2) sets (which data can be obtained from the plaintext MQO files)
using what comes down to this formula
However Im not quite sure how calculate the single 3D points given this resultant XYZ set, so I can't quite automate the process yet howeverGiven 3 points
x1,y1,z1,x2,y2,z2,x3,y3,z3
each with their own UV coordinate
u1,v1,u2,v2,u3,v3
****for UV(1,1)****
p = (u2-u3+v2-u3*v2+(-1+u2)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (u1-u3+v1-u3*v1+(-1+u1)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (u1-u2+v1-u2*v1+(-1+u1)*v2) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
****for UV(0,0)****
p = (u2*v3)-(v2*u3) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
q = (u1*v3)-(v1*u3) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
r = (u1*v2)-(v1*u2) / (u1*v2+u2*v3+u3*v1)-(u3*v2+u2*v1+u1*v3)
****for UV(0,1)****
p = (-(u3*(1+v2))+u2*(1+v3)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (-(u3*(1+v1))+u1*(1+v3)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (-(u2*(1+v1))+u1*(1+v2)) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
****for UV(1,0)****
p = (v2-u3*v2+(-1+u2)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
q = (v1-u3*v1+(-1+u1)*v3) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
r = (v1-u2*v1+(-1+u1)*v2) / (u3*(v1-v2)+u1*(v2-v3)+u2*(-v1+v3))
-----------------------------------------------------------
As you can see the equations to the rights of the divisions are the same.
No need to calculate stuff twice....
you have the general equations for x,y,z
X = x1*p + x2*q + x3*r
Y = y1*p + y2*q + y3*r
Z = z1*p + z2*q + z3*r
using the vertex IDs seems to work alright as long as they're placed in the correct order
(0002 0000 0003)
Heres some more advanced models I textured with this method
Take your spam to the spam section. Not gonna warn again.
« Previous Thread | Next Thread » |
Thread Information |
Users Browsing this ThreadThere are currently 1 users browsing this thread. (0 members and 1 guests) |