use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class CurvesTemporalMesh method loadNurbSurface.
/**
* This method loads the NURBS curve or surface.
* @param nurb
* the NURBS data structure
* @throws BlenderFileException
* an exception is thrown when problems with reading occur
*/
@SuppressWarnings("unchecked")
private void loadNurbSurface(Structure nurb, int materialIndex) throws BlenderFileException {
// loading the knots
List<Float>[] knots = new List[2];
Pointer[] pKnots = new Pointer[] { (Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv") };
for (int i = 0; i < knots.length; ++i) {
if (pKnots[i].isNotNull()) {
FileBlockHeader fileBlockHeader = blenderContext.getFileBlock(pKnots[i].getOldMemoryAddress());
BlenderInputStream blenderInputStream = blenderContext.getInputStream();
blenderInputStream.setPosition(fileBlockHeader.getBlockPosition());
int knotsAmount = fileBlockHeader.getCount() * fileBlockHeader.getSize() / 4;
knots[i] = new ArrayList<Float>(knotsAmount);
for (int j = 0; j < knotsAmount; ++j) {
knots[i].add(Float.valueOf(blenderInputStream.readFloat()));
}
}
}
// loading the flags and orders (basis functions degrees)
int flag = ((Number) nurb.getFieldValue("flag")).intValue();
boolean smooth = (flag & FLAG_SMOOTH) != 0;
int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
// loading control points and their weights
int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData();
List<List<Vector4f>> controlPoints = new ArrayList<List<Vector4f>>(pntsV);
for (int i = 0; i < pntsV; ++i) {
List<Vector4f> uControlPoints = new ArrayList<Vector4f>(pntsU);
for (int j = 0; j < pntsU; ++j) {
DynamicArray<Float> vec = (DynamicArray<Float>) bPoints.get(j + i * pntsU).getFieldValue("vec");
if (blenderContext.getBlenderKey().isFixUpAxis()) {
uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(2).floatValue(), -vec.get(1).floatValue(), vec.get(3).floatValue()));
} else {
uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(1).floatValue(), vec.get(2).floatValue(), vec.get(3).floatValue()));
}
}
if ((flagU & 0x01) != 0) {
for (int k = 0; k < orderU - 1; ++k) {
uControlPoints.add(uControlPoints.get(k));
}
}
controlPoints.add(uControlPoints);
}
if ((flagV & 0x01) != 0) {
for (int k = 0; k < orderV - 1; ++k) {
controlPoints.add(controlPoints.get(k));
}
}
int originalVerticesAmount = vertices.size();
int resolu = ((Number) nurb.getFieldValue("resolu")).intValue();
if (knots[1] == null) {
// creating the NURB curve
Curve curve = new Curve(new Spline(controlPoints.get(0), knots[0]), resolu);
FloatBuffer vertsBuffer = (FloatBuffer) curve.getBuffer(Type.Position).getData();
beziers.add(new BezierLine(BufferUtils.getVector3Array(vertsBuffer), materialIndex, smooth, false));
} else {
// creating the NURB surface
int resolv = ((Number) nurb.getFieldValue("resolv")).intValue();
int uSegments = resolu * controlPoints.get(0).size() - 1;
int vSegments = resolv * controlPoints.size() - 1;
Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, uSegments, vSegments, orderU, orderV, smooth);
FloatBuffer vertsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Position).getData();
vertices.addAll(Arrays.asList(BufferUtils.getVector3Array(vertsBuffer)));
FloatBuffer normalsBuffer = (FloatBuffer) nurbSurface.getBuffer(Type.Normal).getData();
normals.addAll(Arrays.asList(BufferUtils.getVector3Array(normalsBuffer)));
IndexBuffer indexBuffer = nurbSurface.getIndexBuffer();
for (int i = 0; i < indexBuffer.size(); i += 3) {
int index1 = indexBuffer.get(i) + originalVerticesAmount;
int index2 = indexBuffer.get(i + 1) + originalVerticesAmount;
int index3 = indexBuffer.get(i + 2) + originalVerticesAmount;
faces.add(new Face(new Integer[] { index1, index2, index3 }, smooth, materialIndex, null, null, this));
}
}
}
use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.
the class BlenderKey method read.
@Override
public void read(JmeImporter e) throws IOException {
super.read(e);
InputCapsule ic = e.getCapsule(this);
fps = ic.readInt("fps", DEFAULT_FPS);
featuresToLoad = ic.readInt("features-to-load", FeaturesToLoad.ALL);
loadUnlinkedAssets = ic.readBoolean("load-unlinked-assets", false);
assetRootPath = ic.readString("asset-root-path", null);
fixUpAxis = ic.readBoolean("fix-up-axis", true);
generatedTexturePPU = ic.readInt("generated-texture-ppu", 128);
usedWorld = ic.readString("used-world", null);
defaultMaterial = (Material) ic.readSavable("default-material", null);
faceCullMode = ic.readEnum("face-cull-mode", FaceCullMode.class, FaceCullMode.Off);
layersToLoad = ic.readInt("layers-to=load", -1);
mipmapGenerationMethod = ic.readEnum("mipmap-generation-method", MipmapGenerationMethod.class, MipmapGenerationMethod.GENERATE_WHEN_NEEDED);
skyGeneratedTextureSize = ic.readInt("sky-generated-texture-size", 1000);
skyGeneratedTextureRadius = ic.readFloat("sky-generated-texture-radius", 1f);
skyGeneratedTextureShape = ic.readEnum("sky-generated-texture-shape", SkyGeneratedTextureShape.class, SkyGeneratedTextureShape.SPHERE);
optimiseTextures = ic.readBoolean("optimise-textures", false);
animationMatchMethod = ic.readEnum("animation-match-method", AnimationMatchMethod.class, AnimationMatchMethod.AT_LEAST_ONE_NAME_MATCH);
pointsSize = ic.readFloat("points-size", 1);
linesWidth = ic.readFloat("lines-width", 1);
}
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();
}
Aggregations