📄 tdsfile.java
字号:
Spatial spatial;
if ( kfInfo == null ) {
putChildMeshes( myNode, (TriMeshChunk) noc.whatIAm, new Vector3f( 0, 0, 0 ) );
spatial = usedSpatial( myNode );
} else {
putChildMeshes( myNode, (TriMeshChunk) noc.whatIAm, kfInfo.pivot );
spatial = myNode;
nodesByID.put( kfInfo.myID, myNode );
}
spatialNodesNames.add( noc.name );
spatialNodes.add( spatial );
} else if ( noc.whatIAm instanceof LightChunk ) {
spatialLights.add( createChildLight( (LightChunk) noc.whatIAm ) );
}
}
// build hierarchy
if ( keyframes != null ) {
for ( Object o : keyframes.objKeyframes.entrySet() ) {
Map.Entry entry = (Map.Entry) o;
KeyframeInfoChunk kfInfo = (KeyframeInfoChunk) entry.getValue();
if ( kfInfo.parent != -1 ) {
Node node = nodesByID.get( kfInfo.myID );
if ( node != null ) {
Node parentNode = nodesByID.get( kfInfo.parent );
if ( parentNode != null ) {
parentNode.attachChild( node );
} else {
throw new JmeException( "Parent node (id=" + kfInfo.parent + ") not foudn!" );
}
}
}
}
}
}
private Spatial usedSpatial(Node myNode) {
Spatial spatial;
if (myNode.getQuantity()==1){
myNode.getChild(0).setName(myNode.getName());
spatial = myNode.getChild(0);
myNode.detachChild( spatial );
} else {
spatial = myNode;
}
return spatial;
}
private Light createChildLight(LightChunk lightChunk) {
// Light attenuation does not work right.
if (lightChunk.spotInfo!=null){
SpotLight toReturn=new SpotLight();
toReturn.setLocation(lightChunk.myLoc);
toReturn.setDiffuse(lightChunk.lightColor);
toReturn.setAmbient(ColorRGBA.black.clone());
toReturn.setSpecular(ColorRGBA.white.clone());
Vector3f tempDir=lightChunk.myLoc.subtract(lightChunk.spotInfo.target).multLocal(-1);
tempDir.normalizeLocal();
toReturn.setDirection(tempDir);
// toReturn.setAngle(lightChunk.spotInfo.fallOff); // Get this working correctly
toReturn.setAngle(180); // FIXME: Get this working correctly, it's just a hack
toReturn.setEnabled(true);
return toReturn;
}
PointLight toReturn=new PointLight();
toReturn.setLocation(lightChunk.myLoc);
toReturn.setDiffuse(lightChunk.lightColor);
toReturn.setAmbient(ColorRGBA.black.clone());
toReturn.setSpecular(ColorRGBA.white.clone());
toReturn.setEnabled(true);
return toReturn;
}
private void putChildMeshes(Node parentNode, TriMeshChunk whatIAm,Vector3f pivotLoc) throws IOException {
FacesChunk myFace=whatIAm.face;
if (myFace==null) return;
boolean[] faceHasMaterial=new boolean[myFace.nFaces];
int noMaterialCount=myFace.nFaces;
ArrayList<Vector3f> normals=new ArrayList<Vector3f>(myFace.nFaces);
ArrayList<Vector3f> vertexes=new ArrayList<Vector3f>(myFace.nFaces);
Vector3f tempNormal=new Vector3f();
ArrayList<Vector2f> texCoords=new ArrayList<Vector2f>(myFace.nFaces);
if (whatIAm.coordSystem==null)
whatIAm.coordSystem=new TransformMatrix();
whatIAm.coordSystem.inverse();
for ( Vector3f vertexe : whatIAm.vertexes ) {
whatIAm.coordSystem.multPoint( vertexe );
vertexe.subtractLocal( pivotLoc );
}
Vector3f[] faceNormals=new Vector3f[myFace.nFaces];
calculateFaceNormals(faceNormals,whatIAm.vertexes,whatIAm.face.faces);
// Precalculate nextTo[vertex][0...i] <--->
// whatIAm.vertexes[vertex] is next to face nextTo[vertex][0] & nextTo[vertex][i]
if (DEBUG || DEBUG_LIGHT) logger.info("Precaching");
int[] vertexCount=new int[whatIAm.vertexes.length];
for (int i=0;i<myFace.nFaces;i++){
for (int j=0;j<3;j++){
vertexCount[myFace.faces[i][j]]++;
}
}
int[][] realNextFaces=new int[whatIAm.vertexes.length][];
for (int i=0;i<realNextFaces.length;i++)
realNextFaces[i]=new int[vertexCount[i]];
int vertexIndex;
for (int i=0;i<myFace.nFaces;i++){
for (int j=0;j<3;j++){
vertexIndex=myFace.faces[i][j];
realNextFaces[vertexIndex][--vertexCount[vertexIndex]]=i;
}
}
if (DEBUG || DEBUG_LIGHT) logger.info("Precaching done");
int[] indexes=new int[myFace.nFaces*3];
for (int i=0;i<myFace.materialIndexes.size();i++){ // For every original material
String matName=myFace.materialNames.get(i);
int[] appliedFacesIndexes=myFace.materialIndexes.get(i);
if (DEBUG_LIGHT || DEBUG) logger.info("On material " + matName + " with " + appliedFacesIndexes.length + " faces.");
if (appliedFacesIndexes.length!=0){ // If it's got something make a new trimesh for it
TriMesh part = new TriMesh( parentNode.getName() + "##" + i );
normals.clear();
vertexes.clear();
texCoords.clear();
int curPosition = 0;
for (int j=0;j<appliedFacesIndexes.length;j++){ // Look thru every face in that new TriMesh
if (DEBUG) if (j%500==0) logger.info("Face:" + j);
int actuallFace=appliedFacesIndexes[j];
if ( !faceHasMaterial[actuallFace] ){
faceHasMaterial[actuallFace]=true;
noMaterialCount--;
}
for (int k=0;k<3;k++){ // and every vertex in that face
// what faces contain this vertex index? If they do and are in the same SG, average
vertexIndex=myFace.faces[actuallFace][k];
tempNormal.set(faceNormals[actuallFace]);
calcFacesWithVertexAndSmoothGroup(realNextFaces[vertexIndex],faceNormals,myFace,tempNormal,actuallFace);
// Now can I just index this Vertex/tempNormal combination?
int l;
// Vector3f vertexValue=whatIAm.vertexes[vertexIndex];
// for (l=0;l<normals.size();l++) {
// if (normals.get(l).equals(tempNormal) && vertexes.get(l).equals(vertexValue)) {
// break;
// }
// }
// if (l==normals.size()){ // if new
normals.add(new Vector3f(tempNormal));
vertexes.add(whatIAm.vertexes[vertexIndex]);
if (whatIAm.texCoords!=null)
texCoords.add(whatIAm.texCoords[vertexIndex]);
indexes[curPosition++]=normals.size()-1;
// } else { // if old
// indexes[curPosition++]=l;
// }
}
}
Vector3f[] newVerts=new Vector3f[vertexes.size()];
for (int indexV=0;indexV<newVerts.length;indexV++)
newVerts[indexV]=vertexes.get(indexV);
part.setVertexBuffer(BufferUtils.createFloatBuffer(newVerts));
part.setNormalBuffer(BufferUtils.createFloatBuffer(normals
.toArray(new Vector3f[] {})));
if (whatIAm.texCoords != null)
part.setTextureCoords(TexCoords.makeNew(texCoords
.toArray(new Vector2f[] {})));
int[] intIndexes = new int[curPosition];
System.arraycopy(indexes,0,intIndexes,0,curPosition);
part.setIndexBuffer(BufferUtils.createIntBuffer(intIndexes));
MaterialBlock myMaterials=objects.materialBlocks.get(matName);
if (matName==null)
throw new IOException("Couldn't find the correct name of " + myMaterials);
if (myMaterials.myMatState.isEnabled()) {
part.setRenderState(myMaterials.myMatState);
if ( myMaterials.myMatState.getDiffuse().a < 1.0f ) {
part.setRenderQueueMode( Renderer.QUEUE_TRANSPARENT );
if ( alpha == null ) {
alpha = DisplaySystem.getDisplaySystem().getRenderer().createBlendState();
alpha.setEnabled( true );
alpha.setBlendEnabled( true );
alpha.setSourceFunction( BlendState.SourceFunction.SourceAlpha );
alpha.setDestinationFunction( BlendState.DestinationFunction.OneMinusSourceAlpha );
alpha.setTestEnabled( true );
alpha.setTestFunction( BlendState.TestFunction.GreaterThan );
}
part.setRenderState( alpha );
}
}
if (myMaterials.myTexState.isEnabled())
part.setRenderState(myMaterials.myTexState);
if (myMaterials.myWireState.isEnabled())
part.setRenderState(myMaterials.myWireState);
parentNode.attachChild(part);
}
}
if (noMaterialCount!=0){ // attach materialless parts
int[] noMaterialIndexes=new int[noMaterialCount*3];
int partCount=0;
for (int i=0;i<whatIAm.face.nFaces;i++){
if (!faceHasMaterial[i]){
noMaterialIndexes[partCount++]=myFace.faces[i][0];
noMaterialIndexes[partCount++]=myFace.faces[i][1];
noMaterialIndexes[partCount++]=myFace.faces[i][2];
}
}
TriMesh noMaterials=new TriMesh(parentNode.getName()+"-1");
noMaterials.setVertexBuffer(BufferUtils.createFloatBuffer(whatIAm.vertexes));
noMaterials.setIndexBuffer(BufferUtils.createIntBuffer(noMaterialIndexes));
parentNode.attachChild(noMaterials);
}
}
private void calculateFaceNormals(Vector3f[] faceNormals,Vector3f[] vertexes,int[][] faces) {
Vector3f tempa=new Vector3f(),tempb=new Vector3f();
// Face normals
for (int i=0;i<faceNormals.length;i++){
tempa.set(vertexes[faces[i][0]]); // tempa=a
tempa.subtractLocal(vertexes[faces[i][1]]); // tempa-=b (tempa=a-b)
tempb.set(vertexes[faces[i][0]]); // tempb=a
tempb.subtractLocal(vertexes[faces[i][2]]); // tempb-=c (tempb=a-c)
faceNormals[i]=tempa.cross(tempb).normalizeLocal();
}
}
// Find all face normals for faces that contain that vertex AND are in that smoothing group.
private void calcFacesWithVertexAndSmoothGroup(int[] thisVertexTable,Vector3f[] faceNormals,FacesChunk myFace, Vector3f tempNormal, int faceIndex) {
// tempNormal starts out with the face normal value
int smoothingGroupValue=myFace.smoothingGroups[faceIndex];
if (smoothingGroupValue==0)
return; // 0 smoothing group values don't have smooth edges anywhere
for ( int arrayFace : thisVertexTable ) {
if ( arrayFace == faceIndex ) {
continue;
}
if ( ( myFace.smoothingGroups[arrayFace] & smoothingGroupValue ) != 0 ) {
tempNormal.addLocal( faceNormals[arrayFace] );
}
}
tempNormal.normalizeLocal();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -