⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subdivision.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	
	/**
	 * 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 + -