use of com.jme3.scene.shape.Surface in project jmonkeyengine by jMonkeyEngine.
the class NewtonianParticleInfluencer method influenceParticle.
@Override
public void influenceParticle(Particle particle, EmitterShape emitterShape) {
emitterShape.getRandomPointAndNormal(particle.position, particle.velocity);
// influencing the particle's velocity
if (surfaceTangentFactor == 0.0f) {
particle.velocity.multLocal(normalVelocity);
} else {
// calculating surface tangent (velocity contains the 'normal' value)
temp.set(particle.velocity.z * surfaceTangentFactor, particle.velocity.y * surfaceTangentFactor, -particle.velocity.x * surfaceTangentFactor);
if (surfaceTangentRotation != 0.0f) {
// rotating the tangent
Matrix3f m = new Matrix3f();
m.fromAngleNormalAxis(FastMath.PI * surfaceTangentRotation, particle.velocity);
temp = m.multLocal(temp);
}
// applying normal factor (this must be done first)
particle.velocity.multLocal(normalVelocity);
// adding tangent vector
particle.velocity.addLocal(temp);
}
if (velocityVariation != 0.0f) {
this.applyVelocityVariation(particle);
}
}
use of com.jme3.scene.shape.Surface in project jmonkeyengine by jMonkeyEngine.
the class Surface method buildSurface.
/**
* This method creates the surface.
* @param smooth
* defines if the mesu should be smooth (true) or flat (false)
*/
private void buildSurface(boolean smooth) {
float minUKnot = this.getMinUNurbKnot();
float maxUKnot = this.getMaxUNurbKnot();
float deltaU = (maxUKnot - minUKnot) / uSegments;
float minVKnot = this.getMinVNurbKnot();
float maxVKnot = this.getMaxVNurbKnot();
float deltaV = (maxVKnot - minVKnot) / vSegments;
// new Vector3f[(uSegments + 1) * (vSegments + 1)];
List<Vector3f> vertices = new ArrayList<Vector3f>((uSegments + 1) * (vSegments + 1));
float u = minUKnot, v = minVKnot;
for (int i = 0; i <= vSegments; ++i) {
for (int j = 0; j <= uSegments; ++j) {
Vector3f interpolationResult = new Vector3f();
CurveAndSurfaceMath.interpolate(u, v, controlPoints, knots, basisUFunctionDegree, basisVFunctionDegree, interpolationResult);
vertices.add(interpolationResult);
u += deltaU;
}
u = minUKnot;
v += deltaV;
}
if (!smooth) {
// separate the vertices that will share faces (they will need separate normals anyway)
// what happens with the mesh is represented here (be careful with code formatting here !!!)
// * -- * -- * * -- * * -- *
// | | | | | | |
// * -- * -- * * -- * * -- *
// | | | ==> * -- * * -- *
// * -- * -- * | | | |
// | | | * -- * * -- *
// * -- * -- * .............
// first duplicate all verts that are not on the border along the U axis
int uVerticesAmount = uSegments + 1;
int vVerticesAmount = vSegments + 1;
int newUVerticesAmount = 2 + (uVerticesAmount - 2) * 2;
List<Vector3f> verticesWithUDuplicates = new ArrayList<Vector3f>(vVerticesAmount * newUVerticesAmount);
for (int i = 0; i < vertices.size(); ++i) {
verticesWithUDuplicates.add(vertices.get(i));
if (i % uVerticesAmount != 0 && i % uVerticesAmount != uVerticesAmount - 1) {
verticesWithUDuplicates.add(vertices.get(i));
}
}
// and then duplicate all verts that are not on the border along the V axis
List<Vector3f> verticesWithVDuplicates = new ArrayList<Vector3f>(verticesWithUDuplicates.size() * vVerticesAmount);
verticesWithVDuplicates.addAll(verticesWithUDuplicates.subList(0, newUVerticesAmount));
for (int i = 1; i < vSegments; ++i) {
verticesWithVDuplicates.addAll(verticesWithUDuplicates.subList(i * newUVerticesAmount, i * newUVerticesAmount + newUVerticesAmount));
verticesWithVDuplicates.addAll(verticesWithUDuplicates.subList(i * newUVerticesAmount, i * newUVerticesAmount + newUVerticesAmount));
}
verticesWithVDuplicates.addAll(verticesWithUDuplicates.subList(vSegments * newUVerticesAmount, vSegments * newUVerticesAmount + newUVerticesAmount));
vertices = verticesWithVDuplicates;
}
// adding indexes
int[] indices = new int[uSegments * vSegments * 6];
int arrayIndex = 0;
int uVerticesAmount = smooth ? uSegments + 1 : uSegments * 2;
if (smooth) {
for (int i = 0; i < vSegments; ++i) {
for (int j = 0; j < uSegments; ++j) {
indices[arrayIndex++] = j + i * uVerticesAmount + uVerticesAmount;
indices[arrayIndex++] = j + i * uVerticesAmount + 1;
indices[arrayIndex++] = j + i * uVerticesAmount;
indices[arrayIndex++] = j + i * uVerticesAmount + uVerticesAmount;
indices[arrayIndex++] = j + i * uVerticesAmount + uVerticesAmount + 1;
indices[arrayIndex++] = j + i * uVerticesAmount + 1;
}
}
} else {
for (int i = 0; i < vSegments; ++i) {
for (int j = 0; j < uSegments; ++j) {
indices[arrayIndex++] = i * 2 * uVerticesAmount + uVerticesAmount + j * 2;
indices[arrayIndex++] = i * 2 * uVerticesAmount + j * 2 + 1;
indices[arrayIndex++] = i * 2 * uVerticesAmount + j * 2;
indices[arrayIndex++] = i * 2 * uVerticesAmount + uVerticesAmount + j * 2;
indices[arrayIndex++] = i * 2 * uVerticesAmount + uVerticesAmount + j * 2 + 1;
indices[arrayIndex++] = i * 2 * uVerticesAmount + j * 2 + 1;
}
}
}
Vector3f[] verticesArray = vertices.toArray(new Vector3f[vertices.size()]);
// normalMap merges normals of faces that will be rendered smooth
Map<Vector3f, Vector3f> normalMap = new HashMap<Vector3f, Vector3f>(verticesArray.length);
for (int i = 0; i < indices.length; i += 3) {
Vector3f n = FastMath.computeNormal(verticesArray[indices[i]], verticesArray[indices[i + 1]], verticesArray[indices[i + 2]]);
this.addNormal(n, normalMap, smooth, verticesArray[indices[i]], verticesArray[indices[i + 1]], verticesArray[indices[i + 2]]);
}
// preparing normal list (the order of normals must match the order of vertices)
float[] normals = new float[verticesArray.length * 3];
arrayIndex = 0;
for (int i = 0; i < verticesArray.length; ++i) {
Vector3f n = normalMap.get(verticesArray[i]);
normals[arrayIndex++] = n.x;
normals[arrayIndex++] = n.y;
normals[arrayIndex++] = n.z;
}
this.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(verticesArray));
this.setBuffer(VertexBuffer.Type.Index, 3, indices);
this.setBuffer(VertexBuffer.Type.Normal, 3, normals);
this.updateBound();
this.updateCounts();
}
use of com.jme3.scene.shape.Surface 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.shape.Surface in project jmonkeyengine by jMonkeyEngine.
the class TerrainTestModifyHeight method createMarker.
private void createMarker() {
// collision marker
Sphere sphere = new Sphere(8, 8, 0.5f);
marker = new Geometry("Marker");
marker.setMesh(sphere);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", new ColorRGBA(251f / 255f, 130f / 255f, 0f, 0.6f));
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
marker.setMaterial(mat);
rootNode.attachChild(marker);
// surface normal marker
Arrow arrow = new Arrow(new Vector3f(0, 1, 0));
markerNormal = new Geometry("MarkerNormal");
markerNormal.setMesh(arrow);
markerNormal.setMaterial(mat);
rootNode.attachChild(markerNormal);
}
Aggregations