Thanks for the fast reply
But I am confused.
You said "smoothing groups are not exported because they are missing in Unreal model data", so what's that 32 bit value SmoothingGroups in the .psk format?
I thought .psk has smoothing groups. But if it has normals in it instead, I think it's better. Because as you said smoothing groups is not a great way to produce normals, you can't generate smoothing groups from normals because explicit normals have more control.
But smoothing groups aren't needed even for 3ds max I think, 3ds max has Edit Normals modifier which lets you control them so I think I can with MAX script too.
You also said:
"As I mentioned above, I have 2 approaches for normals - generate them from geometry and UV space, or use prebuilt data."
1) How do you generate them? I don't mean a literal max-script, just the general idea in some pseudo code, maybe I can translate it to MAX script.
2) How do you use prebuilt data? Does TERA who uses U3 engine have prebuilt normals in the .psk file? If so, that might explain, but your ActorX importer script doesn't read or do anything about the normals, so I am clueless where they even are in the .psk format
Lastly, even if I calculate the normal properly, or use prebuilt one, I can't seem to find a way to manipulate the tangents and bitangents / binormals of a mesh in 3ds max. It seems it only auto-calculates them with the following code (searched on the web for it)
void ComputeTangentAndBinormal(const Point3 tv[3], const Point3 v[3], Point3 bvec[2])
{
float uva,uvb,uvc,uvd,uvk;
Point3 v1,v2;
int ix = 0; // 0 corresponds to the U axis
int iy = 1; // 1 corresponds to the V axis
uva = tv[1][ix]-tv[0][ix];
uvb = tv[2][ix]-tv[0][ix];
uvc = tv[1][iy]-tv[0][iy];
uvd = tv[2][iy]-tv[0][iy];
uvk = uvb*uvc - uva*uvd;
v1 = v[1]-v[0];
v2 = v[2]-v[0];
if (uvk!=0) {
bvec[0] = FNormalize((uvc*v2-uvd*v1)/uvk);
}
else {
if (uva!=0)
bvec[0] = FNormalize(v1/uva);
else if (uvb!=0)
bvec[0] = FNormalize(v2/uvb);
else
bvec[0] = Point3(0.0f,0.0f,0.0f);
}
Point3 normal = Normalize( (v[1] - v[0]) ^ (v[2] - v[1]) );
bvec[1] = CrossProd( normal, bvec[0] );
Then this code to flip the binormal when the triangle in UV space is back-facing:
Point3 mapNormal = FNormalize((mapTri[1] - mapTri[0]) ^ (mapTri[2] - mapTri[1]));
if( mapNormal.z<0 ) // is the UV face flipped?
basisVec[1] = -basisVec[1]; // yes, so flip the binormal
I also found this MAXscript that computes tangents and binormals:
fn computeTangentSpace obj =
(
local theMesh = snapshotAsMesh obj
local tSpace = #()
for nFace = 1 to theMesh.numFaces do
(
local face = getFace theMesh nFace
local tface = getTVFace theMesh nFace
local v1 = getVert theMesh face[1]
local v2 = getVert theMesh face[2]
local v3 = getVert theMesh face[3]
local w1 = getTVert theMesh tface[1]
local w2 = getTVert theMesh tface[2]
local w3 = getTVert theMesh tface[3]
local x1 = v2.x - v1.x
local x2 = v3.x - v1.x
local y1 = v2.y - v1.y
local y2 = v3.y - v1.y
local z1 = v2.z - v1.z
local z2 = v3.z - v1.z
local s1 = w2.x - w1.x
local s2 = w3.x - w1.x
local t1 = w2.y - w1.y
local t2 = w3.y - w1.y
local r = 1.0 / (s1 * t2 - s2 * t1)
local tan1 = [(t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r]
local tan2 = [(s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r]
local normal = normalize (getFaceNormal theMesh nFace)
local tangent = normalize (tan1 - normal * (dot normal tan1))
local handedness = if (dot (cross normal tan1) tan2) < 0.0 then -1.0 else 1.0
local binormal = (normalize (cross normal tangent)) * handedness
local fCenter = meshOp.getFaceCenter theMesh nFace
append tSpace (Matrix3 tangent binormal normal fCenter)
)
delete theMesh
return tSpace
)
The problem is I can't find a way to manipulate the tangents / binormals in 3ds max at all, I can only let it auto-generate them? This wouldn't be an issue if it did it properly, but for some reason it doesn't, at least for TERA models. And I have a feeling the issue of my inverted lighting on one half is because of the binormal not flipping, but I am not sure.
1) I am using an older version of MAX so any idea if a newer one lets you manipulate tangents and binormals, or it doesn't?
2) If I can't, then how can I make the auto-generation perfect like umodel does - are my normals wrong? (the ones 3ds max auto generates atm) If so, what's the trick umodel generates them perfectly for TERA models? (I may translate it into max script)
3) If it's not the normals being at issue, then what else is wrong with the generation of tangents and binormals, something which umodel doesn't have problems of, but 3ds max does.
I saw this piece of code and I wonder about one part of it:
for i = 1 to numWedges do
(
-- set texture coordinates
w = Wedges[
i]
meshop.setMapVert newMesh 1 i [ w.U, 1-w.V, 1-w.V ] -- V coordinate is flipped
)
What's the 3rd value of the array [ ] for? And why is it 1-w.V same as 2nd ? Could it be that the problem for when MAX auto generates tangents / binormals from UV coords, or am I completely off the point?
Thanks in advance