📄 load3ds.java
字号:
/*
* Copyright 1998 Hewlett-Packard Company
*
* This file may be copied, modified and distributed only in
* accordance with the terms of the limited licence contained
* in the accompanying file LICENSE.TXT.
*/
//package hplb.java3d;
import java.io.*;
import java.util.*;
import java.awt.Component;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.image.TextureLoader;
/**
* .3DS format model loader for Java3D.
* @author Rycharde Hawkes
* @version 1.0
*/
public class Load3DS
{
static final int MAX_SURFACES = 33;
static final int verbosity = 0;
int totalPolygons = 0;
int totalVertices = 0;
//
// Root of the scene graph for the file.
//
BranchGroup root = null;
//
// Lookup table of instances of SharedObjects held
// in <objectTable>, indexed by name.
//
Hashtable instanceTable = null;
//
// Lookup table of all SharedObjects created,
// indexed by name.
//
Hashtable objectTable = null;
//
// Refers to the object currently being constructed.
//
SharedGroup object = null;
//
// Refers to the shape component of the object
// currently being constructed.
//
Shape3D shape = null;
//
// <geometry> == current object's geometry.
// <noofVertices> == number of vertices in the face list.
// <vertices> == vertex array.
// <noofFaces> == number of faces in the object.
// <faces> == list of all the faces in the object.
// <sharedFaces> == list of vertices constructing each face.
// <surfaces> == list of surfaces making up geometry.
// <textureCoords>== list of geometry's texture coordinates.
//
TriangleArray geometry = null;
int noofVertices = 0;
Point3f[] vertices = null;
int noofFaces = 0;
Face[] faces = null;
Vector[] sharedFaces = null;
Surface[] surfaces = null;
Point2f[] textureCoords = null;
//
// Used to indicate whether surfaces were specified
// and created.
//
boolean surfacesCreated = true;
//
// A lookup table of Appearance objects representing
// the materials in the file, indexed by material name.
//
Hashtable mats = null;
//
// <mat> refers to 3DS material currently being constructed.
// <matName> is that name of the 3DS material.
// <material> refers to the counterpart Java3D Material.
//
Appearance mat = null;
String matName = null;
Material material = null;
//
// <shininess> == 3DS shininess percentage.
//
float shininess = 0.0f;
//
// Provided by the constructor of this object, needed
// by the TextureLoader class.
//
Component component = null;
//
// <nodeName> == name of a referenced SharedObject.
// <instanceName> == name of an instance of a SharedObject.
//
String nodeName = null;
String instanceName = null;
//
// <translation> == positional component of the objects' transform.
// <orientation> == rotational component of the objects' transform.
// <scale> == scalar component of the objects' transform.
//
Vector3f translation = null;
Matrix4f orientation = null;
Vector3f scale = null;
String path = null;
/**
* <p>Given a <i>filename</i>, Load3DS will construct an appropriate Java3D scene graph
* - accessible from Load3DS.root(). It also constructs a table of <i>objects</i>,
* indexed by their proper name and a table of <instances> of those objects which
* are refered to by ther instance name. Currently, only two <properties> are
* returned, "polygons" and "vertices", the value of which are a java.lang.Integer
* giving the total number of polygons and vertices in the .3DS file respectively.</p>
* <p>Limitations of the current version:
* <li>Lights are not created.</li>
* <li>Interpretation of 3DS's shininess and shininess strength could be better.</li>
* <li>Only handles those texture map image formats supported by com.sun.j3d.utils.image.TextureLoader.</li>
* </p>
* <p>Java3Disms:
* <li>3DS wireframe material = PolygonAttributes.POLYGON_LINE</li>
* <li>3DS metal-shaded material = PolygonAttributes.POLYGON_POINT</li>
* <li>3DS constant-shaded material = PolygonAttributes.POLYGON_FILL</li>
* <li>3DS phong-shaded material = PolygonAttributes.POLYGON_PHONG</li>
* <li>Hidden objects don't seem to be set by 3DSMax. Load3DS simulates this
* by hiding objects whose names begin with '$'.</li>
* <li>Note that only 3DS planar mapping generates correct 2D texture coords.</li>
* <li>1 generic 3DSMax unit = 1 Java3D unit. This loader does not handle other 3DSMax units,
* e.g. metric.</li>
* </p>
* <p>Known bugs:
* <li>Normal calculation fails for certain surfaces.</li>
* @param filename .3DS file to load.
* @param component parent java.awt.Component (needed by com.sun.j3d.utils.image.TextureLoader).
* @param objects table of named objects indexed by object name. name-value pairs
* are a string and a SharedGroup respectively.
* @param instances table of instanced objects indexed by instance name. name-value
* pairs are a string and a TransformGroup respectively.
* @param properties information about the .3DS file.
* @exception IOException any failure to process .3DS file.
* @see com.sun.j3d.utils.image.TextureLoader
*/
public Load3DS( String filename, Component component,
Hashtable objects, Hashtable instances,
Properties properties )
throws IOException
{
//System.out.println( "Load3DS: loading '" + filename + "'..." );
path = (new java.io.File( filename )).getParent();
if ( path == null )
{
path = ".\\";
}
System.out.println( "Load3DS: using path = " + path );
RandomAccessFile in = new RandomAccessFile( filename, "r" );
this.component = component;
root = new BranchGroup(); // Root of scene graph for this file.
mats = new Hashtable();
objectTable = objects;
instanceTable = instances;
try
{
for ( ;; )
{
processChunk( in );
}
}
catch ( EOFException e )
{
}
properties.put( "polygons", Integer.toString( totalPolygons ) );
properties.put( "vertices", Integer.toString( totalVertices ) );
}
void prepareForNewObject()
{
object = null;
shape = null;
geometry = null;
noofVertices = 0;
vertices = null;
sharedFaces = null;
noofFaces = 0;
faces = null;
surfaces = null;
surfacesCreated = false;
textureCoords = null;
mat = null;
matName = null;
material = null;
shininess = 0.0f;
component = null;
nodeName = null;
instanceName = null;
translation = null;
orientation = null;
scale = null;
}
/**
* Returns the root of the scene graph constructed
* from the given file.
* @return Root of constructed scene graph.
*/
public BranchGroup root()
{
return root;
}
//
// A .3DS file consists of a series of chunks. Each chunk
// starts with a tag ID and the chunks' length followed by
// optional data. This method handles most of those chunks
// processed by this loader. Those chunks that are not
// recognised are ignored.
//
void processChunk( RandomAccessFile in )
throws IOException
{
int tag = readUnsignedShort( in );
int length = readInt( in );
switch ( tag )
{
case S3D_M3DMAGIC: // 3DS file
case S3D_MMAGIC: // Editor chunks
case S3D_MAT_ENTRY: // 3DS material
case S3D_HIERARCHY_NODE: // Object instance
case S3D_N_TRI_OBJECT: // Object definition
processChunk( in );
break;
case S3D_HIERARCHY: // Start of the instance tree
if ( surfacesCreated == false )
{
createUnsmoothedFaces();
prepareForNewObject();
}
processChunk( in );
break;
case S3D_HIERARCHY_LINK: // Details of an object instance
processLink( in );
break;
case S3D_NODE_ID: // Node ID - unused.
processNodeID( in );
break;
case S3D_POS_TRACK_TAG: // Contains object's initial position
processPosTrackTag( in );
break;
case S3D_ROT_TRACK_TAG: // Contains object's initial orientation
processRotTrackTag( in );
break;
case S3D_SCL_TRACK_TAG: // Contains object's initial scale
processSclTrackTag( in );
break;
case S3D_INSTANCE_NAME: // Name given to object instance
instanceName = readName( in );
break;
case S3D_AMBIENT_LIGHT: // Ambient light
processAmbientLight( in );
break;
case S3D_MASTER_SCALE: // Global scaling factor
processMasterScale( in );
break;
case S3D_MAT_NAME: // Start of a 3DS material
matName = readName( in );
mat = new Appearance();
material = new Material();
material.setLightingEnable( true );
mat.setMaterial( material );
mats.put( matName, mat );
if ( verbosity > 2 )
{
System.out.println( "Processing material '" + matName + "'" );
}
break;
case S3D_MAT_AMBIENT: // Ambient colour of material
Color3f ambient = readColor( in );
material.setAmbientColor( ambient );
if ( verbosity > 2 )
{
System.out.println( "== Ambient: " + ambient );
}
break;
case S3D_MAT_DIFFUSE: // Diffuse colour of material
Color3f diffuse = readColor( in );
material.setDiffuseColor( diffuse );
if ( verbosity > 2 )
{
System.out.println( "== Diffuse: " + diffuse );
}
break;
case S3D_MAT_SPECULAR: // Specular colour of material
material.setSpecularColor( readColor( in ) );
break;
case S3D_MAT_SHININESS: // 3DS shininess percentage
shininess = readPercentage( in );
//System.out.println( "== Shininess: " + shininess );
break;
case S3D_MAT_SHININESS_STRENGTH: // 3DS shininess strength
float shininessStrength = readPercentage( in );
//System.out.println( "== Shininess strength: " + shininessStrength );
material.setShininess( (1.0f - ((shininess + shininessStrength) / 2.0f)) * 128 );
break;
case S3D_MAT_TRANSPARENCY: // Transparency percentage
float transparency = readPercentage( in );
if ( verbosity > 2 )
{
System.out.println( "== Transparency: " + transparency );
}
if ( transparency > 0.1f )
{
TransparencyAttributes ta = new TransparencyAttributes();
ta.setTransparency( transparency );
mat.setTransparencyAttributes( ta );
//
// If we turn transparency on then we should
// also turn back face culling off.
//
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace( PolygonAttributes.CULL_NONE );
mat.setPolygonAttributes( pa );
}
break;
case S3D_MAT_SHADING: // Type of rendering
int style;
int mode = readUnsignedShort( in );
PolygonAttributes pa = mat.getPolygonAttributes();
ColoringAttributes ca = mat.getColoringAttributes();
if ( pa == null )
{
pa = new PolygonAttributes();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -