📄 x3dtojme.java
字号:
// if (indices[j] == indices[i]) {
// sortedIndices[j] = i;
// }
// }
// }
// }
// return sortedIndices;
// }
/**
* Generates texture coordinates for a set of vertices defined by the
* specified float array. The texCoords are generated as follows:<br />
* First, the extents of the object defined by the vertices are calculated.
* The coordinate direction with the largest extent will define the S
* texture coordinate, the second largest will define the T coordinate. Now
* the texture coordinates are retrieved from the vertex list. The
* coordinates are scaled so that the lowest space coordinate value will
* correspond to the tex coord value 0 and the highest to 1.<br />
* See the X3D specification for details and examples.
*
* @param vertices
* A list of vertices defined by their coordinate values
* @return The generated texture coordinate array
*/
private float[] generateTexCoords(float[] vertices) {
float[] texCoords = new float[vertices.length / 3 * 2];
float minX = 0;
float maxX = 0;
float minY = 0;
float maxY = 0;
float minZ = 0;
float maxZ = 0;
// Get the extents of the object
for (int i = 0; i * 3 < vertices.length; i++) {
minX = Math.min(minX, vertices[i * 3 + 0]);
maxX = Math.max(maxX, vertices[i * 3 + 0]);
minY = Math.min(minY, vertices[i * 3 + 1]);
maxY = Math.max(maxY, vertices[i * 3 + 1]);
minZ = Math.min(minZ, vertices[i * 3 + 2]);
maxZ = Math.max(maxZ, vertices[i * 3 + 2]);
}
// The coordinate with the largest extent is s, the second largest t
float xExtent = maxX - minX;
float yExtent = maxY - minY;
float zExtent = maxZ - minZ;
int sCoord = 0;
int tCoord = 1;
// default order: X-Y-Z
if (yExtent > xExtent) {
if (zExtent > yExtent) { // order: Z-Y-X
sCoord = 2;
tCoord = 1;
} else {
sCoord = 1;
if (zExtent > xExtent) { // order: Y-Z-X
tCoord = 2;
} else { // order: Y-X-Z
tCoord = 0;
}
}
} else {
if (zExtent > xExtent) { // order: Z-X-Y
sCoord = 2;
tCoord = 0;
} else {
if (zExtent > yExtent) { // order: X-Z-Y
tCoord = 2;
} // else order: X-Y-Z (default)
}
}
// Fill the texCoords array
float[] minValues = { minX, minY, minZ };
float[] extents = { xExtent, yExtent, zExtent };
for (int i = 0; i * 3 < vertices.length; i++) {
texCoords[i * 2 + 0] = (vertices[i * 3 + sCoord] - minValues[sCoord])
/ extents[sCoord];
texCoords[i * 2 + 1] = (vertices[i * 3 + tCoord] - minValues[tCoord])
/ extents[tCoord];
}
return texCoords;
}
/**
* Parses an X3D Sphere node and creates a corresponding jME Sphere.
*
* @param node
* The X3D Sphere node
* @param title
* A title for the sphere. If <code>null</code> is passed, a
* generic title is used.
* @return The jME Sphere
*/
private Sphere parseSphere(Node node, String title) {
Sphere sphere = null;
String radius = node.getAttributes().getNamedItem("radius")
.getNodeValue().trim();
float r = getFloat(radius, 1);
if (title != null) {
sphere = new Sphere(title, SPHERE_Z_SAMPLES, SPHERE_RADIAL_SAMPLES,
r);
} else {
sphere = new Sphere("X3D_Sphere", SPHERE_Z_SAMPLES,
SPHERE_RADIAL_SAMPLES, r);
}
sphere.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI,
Vector3f.UNIT_X);
return sphere;
}
/**
* Parses an X3D Cylinder node and creates a corresponding jME Cylinder
*
* @param node
* The X3D Cylinder node
* @param title
* A title for the cylinder. If <code>null</code> is passed, a
* generic title is used.
* @return The jME Cylinder
*/
private Cylinder parseCylinder(Node node, String title) {
// TODO: Implement the possibility to fully use the "top", "bottom" and
// "side" attributes
Cylinder cylinder = null;
String heightAtt = node.getAttributes().getNamedItem("height")
.getNodeValue().trim();
float height = getFloat(heightAtt, 2);
String radiusAtt = node.getAttributes().getNamedItem("radius")
.getNodeValue().trim();
float radius = getFloat(radiusAtt, 1);
Node topNode = node.getAttributes().getNamedItem("top");
boolean top = true;
if (topNode != null) {
String topAtt = topNode.getNodeValue().trim();
top = Boolean.valueOf(topAtt);
}
Node botNode = node.getAttributes().getNamedItem("bottom");
boolean bottom = true;
if (botNode != null) {
String bottomAtt = botNode.getNodeValue().trim();
bottom = Boolean.valueOf(bottomAtt);
}
if (title != null) {
cylinder = new Cylinder(title, CYLINDER_AXIS_SAMPLES,
CYLINDER_RADIAL_SAMPLES, radius, height, (top && bottom));
} else {
cylinder = new Cylinder("X3D_Cylinder", CYLINDER_AXIS_SAMPLES,
CYLINDER_RADIAL_SAMPLES, radius, height, (top && bottom));
}
cylinder.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI,
Vector3f.UNIT_X);
return cylinder;
}
/**
* Parses an X3D Cone node and creates a corresponding jME Cone
*
* @param node
* The X3D Cone node
* @param title
* A title for the cone. If <code>null</code> is passed, a
* generic title is used.
* @return The jME Cone
*/
private Geometry parseCone(Node node, String title) {
String heightAtt = node.getAttributes().getNamedItem("height")
.getNodeValue().trim();
float height = getFloat(heightAtt, 2);
String radiusAtt = node.getAttributes().getNamedItem("bottomRadius")
.getNodeValue().trim();
float radius = getFloat(radiusAtt, 1);
Node sideNode = node.getAttributes().getNamedItem("side");
boolean side = true;
if (sideNode != null) {
String sideAtt = sideNode.getNodeValue().trim();
side = Boolean.valueOf(sideAtt);
}
boolean bottom = true;
Node botNode = node.getAttributes().getNamedItem("bottom");
if (botNode != null) {
String bottomAtt = botNode.getNodeValue().trim();
bottom = Boolean.valueOf(bottomAtt);
}
if (side) {
// Sides active: Create a cone
Cone cone = null;
if (title != null) {
cone = new Cone(title, CYLINDER_AXIS_SAMPLES,
CYLINDER_RADIAL_SAMPLES, radius, height, bottom);
} else {
cone = new Cone("X3D_Cone", CYLINDER_AXIS_SAMPLES,
CYLINDER_RADIAL_SAMPLES, radius, height, bottom);
}
cone.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI,
Vector3f.UNIT_X);
return cone;
} else {
// Sides deactivated: Create only the disk for the bottom
Disk disk = null;
if (title != null) {
disk = new Disk(title, 1, CYLINDER_RADIAL_SAMPLES, radius);
} else {
disk = new Disk("X3D_Cone", 1, CYLINDER_RADIAL_SAMPLES, radius);
}
disk.setLocalTranslation(0, -height * 0.5f, 0);
disk.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI,
Vector3f.UNIT_X);
return disk;
}
}
/**
* Parses an X3D LineSet node and creates a corresponding jME Line
*
* @param node
* The X3D LineSet node
* @param title
* A title for the LineSet. If <code>null</code> is passed, a
* generic title is used.
* @return The jME Line
*/
private Line parseLS(Node node, String title) {
// jME doesn't need vertexCount, because the Line constructor is smart
// enough to know how many vertices exist just from the float list.
// Thus it is commented out.
// String vertexCountAtt =
// node.getAttributes().getNamedItem("vertexCount").getNodeValue();
// int vertexCount = getInt(vertexCountAtt, 2);
// Parse the vertices
float[] vertices = null;
Node coords = getChildNode(node, "Coordinate");
if (coords != null) {
vertices = parseValues(coords, "point");
}
if (vertices == null) {
return null;
}
// Parse the colors
float[] colorValues = null;
int colorSize = 3; // Number of values per color (Color or ColorRGBA)
Node colors = getChildNode(node, "Color");
if (colors == null) {
colorSize = 4;
colors = getChildNode(node, "ColorRGBA");
}
if (colors != null) {
colorValues = parseValues(colors, "color");
}
// Expand RGB color values to RGBA values
if (colorValues != null && colorSize == 3) {
float[] temp = new float[colorValues.length / 3 * 4];
for (int i = 0; i * 3 < colorValues.length; i++) {
temp[i * 4 + 0] = colorValues[i * 3 + 0];
temp[i * 4 + 1] = colorValues[i * 3 + 1];
temp[i * 4 + 2] = colorValues[i * 3 + 2];
temp[i * 4 + 3] = 1.0f;
}
colorValues = temp;
colorSize = 4;
}
// Create the Line
FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertices);
FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(colorValues);
String name = (title != null) ? title : "X3D_LineSet";
Line line = new Line(name, vertexBuffer, null, colorBuffer, null);
line.setMode(Line.Mode.Connected);
return line;
}
/**
* Parses an X3D Appearance node and generates the corresponding
* RenderStates.
*
* @param node
* The X3D Appearance node
* @return An array containing the created RenderStates
*/
private RenderState[] parseAppearance(Node node) {
// Check for the USE attribute
Node use = node.getAttributes().getNamedItem("USE");
if (use != null) {
return getRenderStateDEFs(use.getNodeValue());
}
ArrayList<RenderState> states = new ArrayList<RenderState>(3);
// Check Texture
TextureState textureState = null;
Node texNode = getChildNode(node, "ImageTexture");
if (texNode != null) {
Texture texture = parseTexture(texNode, null, 0);
if (texture != null) {
textureState = DisplaySystem.getDisplaySystem().getRenderer()
.createTextureState();
textureState.setEnabled(true);
textureState.setTexture(texture);
}
} else {
texNode = getChildNode(node, "MultiTexture");
if (texNode != null) {
textureState = parseMultiTexture(texNode);
}
}
if (textureState != null) {
states.add(textureState);
}
// Check Material
Node materialNode = getChildNode(node, "Material");
if (materialNode != null) {
RenderState[] matStates = parseMaterial(materialNode);
for (RenderState state : matStates) {
if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -