use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class MikktspaceTangentGenerator method generateTSpaces.
static boolean generateTSpaces(TSpace[] psTspace, final TriInfo[] pTriInfos, final Group[] pGroups, final int iNrActiveGroups, final int[] piTriListIn, final float fThresCos, final MikkTSpaceContext mikkTSpace) {
TSpace[] pSubGroupTspace;
SubGroup[] pUniSubGroups;
int[] pTmpMembers;
int iMaxNrFaces = 0, iUniqueTspaces = 0, g = 0, i = 0;
for (g = 0; g < iNrActiveGroups; g++) {
if (iMaxNrFaces < pGroups[g].nrFaces) {
iMaxNrFaces = pGroups[g].nrFaces;
}
}
if (iMaxNrFaces == 0) {
return true;
}
// make initial allocations
pSubGroupTspace = new TSpace[iMaxNrFaces];
pUniSubGroups = new SubGroup[iMaxNrFaces];
pTmpMembers = new int[iMaxNrFaces];
iUniqueTspaces = 0;
for (g = 0; g < iNrActiveGroups; g++) {
final Group pGroup = pGroups[g];
int iUniqueSubGroups = 0, s = 0;
for (// triangles
i = 0; // triangles
i < pGroup.nrFaces; // triangles
i++) {
// triangle number
final int f = pGroup.faceIndices.get(i);
int index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0, l = 0;
SubGroup tmp_group = new SubGroup();
boolean bFound;
Vector3f n, vOs, vOt;
if (pTriInfos[f].assignedGroup[0] == pGroup) {
index = 0;
} else if (pTriInfos[f].assignedGroup[1] == pGroup) {
index = 1;
} else if (pTriInfos[f].assignedGroup[2] == pGroup) {
index = 2;
}
assert (index >= 0 && index < 3);
iVertIndex = piTriListIn[f * 3 + index];
assert (iVertIndex == pGroup.vertexRepresentitive);
// is normalized already
n = getNormal(mikkTSpace, iVertIndex);
// project
vOs = pTriInfos[f].os.subtract(n.mult(n.dot(pTriInfos[f].os)));
vOt = pTriInfos[f].ot.subtract(n.mult(n.dot(pTriInfos[f].ot)));
vOs.normalizeLocal();
vOt.normalizeLocal();
// original face number
iOF_1 = pTriInfos[f].orgFaceNumber;
iMembers = 0;
for (j = 0; j < pGroup.nrFaces; j++) {
// triangle number
final int t = pGroup.faceIndices.get(j);
final int iOF_2 = pTriInfos[t].orgFaceNumber;
// project
Vector3f vOs2 = pTriInfos[t].os.subtract(n.mult(n.dot(pTriInfos[t].os)));
Vector3f vOt2 = pTriInfos[t].ot.subtract(n.mult(n.dot(pTriInfos[t].ot)));
vOs2.normalizeLocal();
vOt2.normalizeLocal();
{
final boolean bAny = ((pTriInfos[f].flag | pTriInfos[t].flag) & GROUP_WITH_ANY) != 0;
// make sure triangles which belong to the same quad are joined.
final boolean bSameOrgFace = iOF_1 == iOF_2;
final float fCosS = vOs.dot(vOs2);
final float fCosT = vOt.dot(vOt2);
// sanity check
assert (f != t || bSameOrgFace);
if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos)) {
pTmpMembers[iMembers++] = t;
}
}
}
// sort pTmpMembers
tmp_group.nrFaces = iMembers;
tmp_group.triMembers = pTmpMembers;
if (iMembers > 1) {
quickSort(pTmpMembers, 0, iMembers - 1, INTERNAL_RND_SORT_SEED);
}
// look for an existing match
bFound = false;
l = 0;
while (l < iUniqueSubGroups && !bFound) {
bFound = compareSubGroups(tmp_group, pUniSubGroups[l]);
if (!bFound) {
++l;
}
}
// assign tangent space index
assert (bFound || l == iUniqueSubGroups);
// if no match was found we allocate a new subgroup
if (!bFound) {
// insert new subgroup
int[] pIndices = new int[iMembers];
pUniSubGroups[iUniqueSubGroups] = new SubGroup();
pUniSubGroups[iUniqueSubGroups].nrFaces = iMembers;
pUniSubGroups[iUniqueSubGroups].triMembers = pIndices;
System.arraycopy(tmp_group.triMembers, 0, pIndices, 0, iMembers);
//memcpy(pIndices, tmp_group.pTriMembers, iMembers*sizeof(int));
pSubGroupTspace[iUniqueSubGroups] = evalTspace(tmp_group.triMembers, iMembers, piTriListIn, pTriInfos, mikkTSpace, pGroup.vertexRepresentitive);
++iUniqueSubGroups;
}
// output tspace
{
final int iOffs = pTriInfos[f].tSpacesOffs;
final int iVert = pTriInfos[f].vertNum[index];
TSpace pTS_out = psTspace[iOffs + iVert];
assert (pTS_out.counter < 2);
assert (((pTriInfos[f].flag & ORIENT_PRESERVING) != 0) == pGroup.orientPreservering);
if (pTS_out.counter == 1) {
pTS_out.set(avgTSpace(pTS_out, pSubGroupTspace[l]));
// update counter
pTS_out.counter = 2;
pTS_out.orient = pGroup.orientPreservering;
} else {
assert (pTS_out.counter == 0);
pTS_out.set(pSubGroupTspace[l]);
// update counter
pTS_out.counter = 1;
pTS_out.orient = pGroup.orientPreservering;
}
}
}
iUniqueTspaces += iUniqueSubGroups;
}
return true;
}
use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class MikktspaceTangentGenerator method evalTspace.
static TSpace evalTspace(int[] face_indices, final int iFaces, final int[] piTriListIn, final TriInfo[] pTriInfos, final MikkTSpaceContext mikkTSpace, final int iVertexRepresentitive) {
TSpace res = new TSpace();
float fAngleSum = 0;
for (int face = 0; face < iFaces; face++) {
final int f = face_indices[face];
// only valid triangles get to add their contribution
if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0) {
int i = -1;
if (piTriListIn[3 * f + 0] == iVertexRepresentitive) {
i = 0;
} else if (piTriListIn[3 * f + 1] == iVertexRepresentitive) {
i = 1;
} else if (piTriListIn[3 * f + 2] == iVertexRepresentitive) {
i = 2;
}
assert (i >= 0 && i < 3);
// project
int index = piTriListIn[3 * f + i];
Vector3f n = getNormal(mikkTSpace, index);
Vector3f vOs = pTriInfos[f].os.subtract(n.mult(n.dot(pTriInfos[f].os)));
Vector3f vOt = pTriInfos[f].ot.subtract(n.mult(n.dot(pTriInfos[f].ot)));
vOs.normalizeLocal();
vOt.normalizeLocal();
int i2 = piTriListIn[3 * f + (i < 2 ? (i + 1) : 0)];
int i1 = piTriListIn[3 * f + i];
int i0 = piTriListIn[3 * f + (i > 0 ? (i - 1) : 2)];
Vector3f p0 = getPosition(mikkTSpace, i0);
Vector3f p1 = getPosition(mikkTSpace, i1);
Vector3f p2 = getPosition(mikkTSpace, i2);
Vector3f v1 = p0.subtract(p1);
Vector3f v2 = p2.subtract(p1);
// project
v1.subtractLocal(n.mult(n.dot(v1))).normalizeLocal();
v2.subtractLocal(n.mult(n.dot(v2))).normalizeLocal();
// weight contribution by the angle
// between the two edge vectors
float fCos = v1.dot(v2);
fCos = fCos > 1 ? 1 : (fCos < (-1) ? (-1) : fCos);
float fAngle = (float) Math.acos(fCos);
float fMagS = pTriInfos[f].magS;
float fMagT = pTriInfos[f].magT;
res.os.addLocal(vOs.multLocal(fAngle));
res.ot.addLocal(vOt.multLocal(fAngle));
res.magS += (fAngle * fMagS);
res.magT += (fAngle * fMagT);
fAngleSum += fAngle;
}
}
// normalize
res.os.normalizeLocal();
res.ot.normalizeLocal();
if (fAngleSum > 0) {
res.magS /= fAngleSum;
res.magT /= fAngleSum;
}
return res;
}
use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class MikkTSpaceImpl method getNormal.
@Override
public void getNormal(float[] normOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer normal = mesh.getBuffer(VertexBuffer.Type.Normal);
FloatBuffer norm = (FloatBuffer) normal.getData();
norm.position(vertIndex * 3);
normOut[0] = norm.get();
normOut[1] = norm.get();
normOut[2] = norm.get();
}
use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class MikkTSpaceImpl method setTSpaceBasic.
@Override
public void setTSpaceBasic(float[] tangent, float sign, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer tangentBuffer = mesh.getBuffer(VertexBuffer.Type.Tangent);
FloatBuffer tan = (FloatBuffer) tangentBuffer.getData();
tan.position(vertIndex * 4);
tan.put(tangent);
tan.put(sign);
tan.rewind();
tangentBuffer.setUpdateNeeded();
}
use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class MikkTSpaceImpl method getPosition.
@Override
public void getPosition(float[] posOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer position = mesh.getBuffer(VertexBuffer.Type.Position);
FloatBuffer pos = (FloatBuffer) position.getData();
pos.position(vertIndex * 3);
posOut[0] = pos.get();
posOut[1] = pos.get();
posOut[2] = pos.get();
}
Aggregations