📄 subdivision.java
字号:
/**
* Computes the normals for the set batch
*
*/
public void computeNormals() {
computeNormals(mesh);
}
/**
* Computes normals for the given batch. Taken from
* com.jmex.model.XMLparser.Converters.AseToJme.java (and optimized).
* Should be overridden since there are methods for each subdivision scheme
* to compute new normals, which give better results.
*
* @param batch
*/
public void computeNormals(TriMesh batch) {
Vector3f vector1 = new Vector3f();
Vector3f vector2 = new Vector3f();
Vector3f vector3 = new Vector3f();
FloatBuffer vb = batch.getVertexBuffer();
IntBuffer ib = batch.getIndexBuffer();
int tCount = batch.getTriangleCount();
int vCount = batch.getVertexCount();
// Get the current object
// Here we allocate all the memory we need to calculate the normals
Vector3f[] tempNormals = new Vector3f[tCount];
Vector3f[] normals = new Vector3f[vCount];
// Go through all of the faces of this object
for (int i = 0; i < tCount; i++) {
BufferUtils.populateFromBuffer(vector1, vb, ib.get(i*3));
BufferUtils.populateFromBuffer(vector2, vb, ib.get(i*3+1));
BufferUtils.populateFromBuffer(vector3, vb, ib.get(i*3+2));
vector1.subtractLocal(vector3);
tempNormals[i] = vector1.cross(vector3.subtract(vector2)).normalizeLocal();
}
Vector3f sum = new Vector3f();
int shared = 0;
for (int i = 0; i < vCount; i++) {
for (int j = 0; j < tCount; j++) {
if (ib.get(j*3) == i
|| ib.get(j*3+1) == i
|| ib.get(j*3+2) == i) {
sum.addLocal(tempNormals[j]);
shared++;
}
}
normals[i] = sum.divide((-shared)).normalizeLocal();
sum.zero(); // Reset the sum
shared = 0; // Reset the shared
}
batch.setNormalBuffer(BufferUtils.createFloatBuffer(normals));
}
/**
* Unsets the batch. Does not clear the buffer lists.
*
*/
public void unsetBatch() {
this.mesh = null;
}
/**
* Add a buffer to the list of buffers who are to be subdivided
*
* @param buffer The buffer to be added
* @param elemSize The size of the elements in the buffer (e.g. 3 for normal buffers, 2 for texture buffers, 4 for color buffers)
* @param linear Whether or not the buffer should be linearly interpolated (for example, it doesn't make sense to use higher-order interpolation on texture coordinates). Should probably be <code>false</code> in most cases
* @param type The type of buffer, needed when applying buffers back to the batch
*/
public void addToBufferList(FloatBuffer buffer, int elemSize, boolean linear, BufferType type) {
buffers.add(new SubdivisionBuffer(buffer, elemSize, linear, type));
}
/**
* Add a buffer to the list of buffers who are to be subdivided
*
* @param buffer The buffer to be added
* @param type The type of buffer, needed when applying buffers back to the batch
*/
public void addToBufferList(FloatBuffer buffer, BufferType type) {
buffers.add(new SubdivisionBuffer(buffer, type));
}
/**
* Removes a buffer from the bufferlist
*
* @param buffer The buffer to remove from the list of buffers to be subdivided
*/
public void removeBuffer(FloatBuffer buffer) {
SubdivisionBuffer removeBuf = null;
boolean found = false;
for (Iterator<SubdivisionBuffer> it = buffers.iterator(); it.hasNext() && (!found); ) {
removeBuf = it.next();
if (removeBuf.buf == buffer) found = true;
}
buffers.remove(removeBuf);
}
/**
* Clear the list of buffers to be interpolated
*
*/
public void clearBufferList() {
buffers = new ArrayList<SubdivisionBuffer>();
}
/**
* Checks whether the buffers submitted to this Subdivision are valid (i.e. if they have as many elements as there are vertices in the vertexbuffer)
* @return <code>true</code> if valid
*/
public boolean isValid() {
boolean valid = true;
String errors = "";
SubdivisionBuffer subBuf;
int vertexCount = vertexBuffer.capacity() / 3;
for (int i = 0; i<buffers.size(); i++) {
subBuf = buffers.get(i);
if (subBuf != null)
if ((subBuf.buf.capacity() / subBuf.elemSize) != vertexCount) {
// The buffer does not have as many elements as there are vertices
valid = false;
errors = errors + "SubdivisionBuffer at index " + i + " does not have as many elements as there are vertices in the vertex buffer.\n";
}
}
if (!valid) {
logger.warning(errors);
}
return valid;
}
/**
* @return Returns the batch.
*/
public TriMesh getBatch() {
return mesh;
}
/**
* @return Returns the indexBuffer.
*/
public IntBuffer getIndexBuffer() {
return indexBuffer;
}
/**
* @param indexBuffer The indexBuffer to set.
*/
public void setIndexBuffer(IntBuffer indexBuffer) {
this.indexBuffer = indexBuffer;
prepared = false;
}
/**
* @return Returns the vertexBuffer.
*/
public FloatBuffer getVertexBuffer() {
return vertexBuffer;
}
/**
* @param vertexBuffer The vertexBuffer to set.
*/
public void setVertexBuffer(FloatBuffer vertexBuffer) {
this.vertexBuffer = vertexBuffer;
prepared = false;
}
/**
* Get the vertex count of the set vertex buffer (capacity / 3)
*
* @return The vertex count
*/
public int getVertexCount() {
if (vertexBuffer == null) {
logger.warning("No vertex buffer set, aborting.");
return 0;
}
return vertexBuffer.capacity() / 3;
}
/**
* Buffer types. Needed to know where to apply buffers to the batch.
* @author Tobias
*/
public enum BufferType {COLORBUFFER,TEXTUREBUFFER,NORMALBUFFER,OTHER}
protected class SubdivisionBuffer {
/**
* The buffer
*/
public FloatBuffer buf;
/**
* The buffer's element size (e.g. 3 for normal buffers, 2 for texture buffers, 4 for color buffers)
*/
public int elemSize;
/**
* Whether or not the buffer should be linearly interpolated
* (for example, it doesn't make sense to use higher-order
* interpolation on texture coordinates, should probably be
* <code>false</code> in most cases)
*/
public boolean linear;
/**
* states which type of buffer this is
*/
public BufferType type;
/**
* Constructor for SubdivisionBuffer
* @param buf The buffer
* @param elemSize The buffer's element size (e.g. 3 for normal buffers, 2 for texture buffers, 4 for color buffers)
* @param linear Whether or not the buffer should be linearly interpolated (for example, it doesn't make sense to use higher-order interpolation on texture coordinates). Should probably be <code>false</code> in most cases
* @param type The type of buffer, needed when applying buffers to batches
*/
public SubdivisionBuffer(FloatBuffer buf, int elemSize, boolean linear, BufferType type) {
this.buf = buf;
this.elemSize = elemSize;
this.linear = linear;
this.type = type;
}
/**
* Constructor for SubdivisionBuffer
* @param buf The buffer
* @param type The type of buffer, needed when applying buffers to batches
*/
public SubdivisionBuffer(FloatBuffer buf, BufferType type) {
this.buf = buf;
switch (type) {
case COLORBUFFER:
this.elemSize = 4;
this.linear = false;
break;
case TEXTUREBUFFER:
this.elemSize = 2;
this.linear = true;
break;
case NORMALBUFFER:
this.elemSize = 3;
this.linear = false;
break;
default:
logger.warning("Unknown buffer type, guessing its elemSize and linearity");
this.elemSize = 3;
this.linear = false;
break;
}
this.type = type;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -