📄 clothpatch.java
字号:
float minY = springLength * (0.5f * (clothNodesY - 1) - 0);
float maxY = springLength
* (0.5f * (clothNodesY - 1) - (clothNodesY - 1));
Vector3f upperLeft = new Vector3f(minX, minY, 0);
Vector3f lowerLeft = new Vector3f(minX, maxY, 0);
Vector3f lowerRight = new Vector3f(maxX, maxY, 0);
Vector3f upperRight = new Vector3f(maxX, minY, 0);
initCloth(nodeMass, upperLeft, lowerLeft, lowerRight, upperRight);
}
/**
* Initialize the values of the vertex, normal and texture[0] arrays. Build
* a SpringSystem and call setupIndices(). Then update the various buffers.
*
* @param nodeMass
* mass of individual node.
* @param upperLeft
* the upper left corner of the rectangle.
* @param lowerLeft
* the lower left corner of the rectangle.
* @param lowerRight
* the lower right corner of the rectangle.
* @param upperRight
* the upper right corner of the rectangle.
*/
protected void initCloth(float nodeMass, Vector3f upperLeft,
Vector3f lowerLeft, Vector3f lowerRight, Vector3f upperRight) {
// Setup our shared vectors as a bilinear combination of the 4 corners
Vector2f texcoord = new Vector2f();
Vector3f vert = new Vector3f();
Vector3f topVec = new Vector3f();
Vector3f bottomVec = new Vector3f();
FloatBuffer texs = getTextureCoords().get(0).coords;
for (int j = 0; j < clothNodesY; j++) {
for (int i = 0; i < clothNodesX; i++) {
int ind = getIndex(i, j);
// vert.set(springLength * (i - 0.5f * (clothNodesX - 1)),
// springLength * (0.5f * (clothNodesY - 1) - j), 0);
float xInterpolation = ((float) i) / (clothNodesX - 1);
topVec.interpolate(upperLeft, upperRight, xInterpolation);
bottomVec.interpolate(lowerLeft, lowerRight, xInterpolation);
vert.interpolate(topVec, bottomVec, ((float) j)
/ (clothNodesY - 1));
BufferUtils.setInBuffer(vert, getVertexBuffer(), ind);
texcoord.set((float) i / (clothNodesX - 1),
(float) (clothNodesY - (j + 1)) / (clothNodesY - 1));
BufferUtils.setInBuffer(texcoord, texs, ind);
}
}
system = SpringSystem.createRectField(clothNodesX, clothNodesY,
getVertexBuffer(), nodeMass);
setupIndices();
}
/**
* Return the underlying SpringSystem.
*
* @return SpringSystem
*/
public SpringSystem getSystem() {
return system;
}
/**
* Return how many nodes high this cloth is.
*
* @return int
*/
public int getClothNodesY() {
return clothNodesY;
}
/**
* Return how many nodes wide this cloth is.
*
* @return int
*/
public int getClothNodesX() {
return clothNodesX;
}
/**
* Return the preset length the <i>structural</i> springs are set to. (ie.
* the springs running along the x and y axis connecting immediate
* neighbors.)
*
* @return float
*/
public float getSpringLength() {
return springLength;
}
/**
* Get the time dilation factor. See <code>setTimeDilation(float)</code>
* for more.
*
* @return float
*/
public float getTimeDilation() {
return timeDilation;
}
/**
* Set the timedilation factor used in <code>updateWorldData(float)</code>
* Normally this is set to 1. If set at 2, for example, every 25 ms of real
* time, the code will update the SpringSystem and cloth as if 50 ms had
* passed.
*
* @param timeDilation
* float
*/
public void setTimeDilation(float timeDilation) {
this.timeDilation = timeDilation;
}
/**
* Setup the triangle indices for this cloth.
*/
protected void setupIndices() {
getIndexBuffer().rewind();
for (int Y = 0; Y < clothNodesY - 1; Y++) {
for (int X = 0; X < clothNodesX - 1; X++) {
getIndexBuffer().put(getIndex(X, Y));
getIndexBuffer().put(getIndex(X, Y + 1));
getIndexBuffer().put(getIndex(X + 1, Y + 1));
getIndexBuffer().put(getIndex(X, Y));
getIndexBuffer().put(getIndex(X + 1, Y + 1));
getIndexBuffer().put(getIndex(X + 1, Y));
}
}
}
/**
* Convienence method for calculating the array index of a given node given
* it's x and y coordiates.
*
* @param x
* int
* @param y
* int
* @return index
*/
protected int getIndex(int x, int y) {
return y * clothNodesX + x;
}
/**
* Update the physics of this cloth. Updates at 40 FPS (every 25 ms)
*
* @param dt
* time since last call to this method. Used to determine if
* enough time has passed to require an update of the
* SpringSystem and cloth data, normals, etc.
*/
public void updateWorldData(float dt) {
super.updateWorldData(dt);
sinceLast += dt;
if (sinceLast >= 0.025f) { // update physics at 40 FPS
sinceLast *= timeDilation;
calcForces(sinceLast);
doUpdate(sinceLast);
sinceLast = 0;
}
}
/**
* Calculate the forces accting on this cloth. Called by
* <code>updateWorldData(float)</code>
*
* @param sinceLast
* float
*/
protected void calcForces(float sinceLast) {
system.calcForces(sinceLast);
}
/**
* Update the spring system underlying this cloth. Called by
* <code>updateWorldData(float)</code>
*
* @param sinceLast
* float
*/
protected void doUpdate(float sinceLast) {
system.update(sinceLast);
updateVertexBufferfer();
updateNormals();
}
protected void updateVertexBufferfer() {
getVertexBuffer().rewind();
for (int x = 0; x < system.getNodeCount(); x++) {
SpringPoint n = system.getNode(x);
getVertexBuffer().put(n.position.x).put(n.position.y).put(
n.position.z);
}
}
public void write(JMEExporter e) throws IOException {
super.write(e);
OutputCapsule capsule = e.getCapsule(this);
capsule.write(clothNodesX, "clothNodesX", 0);
capsule.write(clothNodesY, "clothNodesY", 0);
capsule.write(springLength, "springLength", 0);
capsule.write(system, "system", null);
capsule.write(timeDilation, "timeDilation", 1);
}
public void read(JMEImporter e) throws IOException {
super.read(e);
InputCapsule capsule = e.getCapsule(this);
clothNodesX = capsule.readInt("clothNodesX", 0);
clothNodesY = capsule.readInt("clothNodesY", 0);
springLength = capsule.readFloat("springLength", 0);
system = (SpringSystem) capsule.readSavable("system", null);
timeDilation = capsule.readFloat("timeDilation", 1);
if (system == null) {
initCloth(0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -