📄 nokia3d.java
字号:
VertexBuffer vb = tnl.getVertexBuffer();
// Get vertex count
int count = vb.getVertexCount();
// We must check to see if this implementation supports 2 texture units, before we go any further.
numTextureUnits = ((Integer) g3d.getProperties().get("numTextureUnits")).intValue();
if(numTextureUnits > 1)
{
// Create a new array for texture coordinates (for texture #2, as the object has only one texture layer defined in swerve)
tunnelTexCoords = new short[count * 2];
// Init the array with some random values
for (int a = 0 ; a < count*2; a++)
{
int i = (m_random.nextInt() & 0xFF);
tunnelTexCoords[a] = (short) i;
}
// Create a new vertex array..
tunnelTextureArray = new VertexArray(count, 2, 2);
// Copy texture coordinate values to array
tunnelTextureArray.set(0, count, tunnelTexCoords);
// Assign texture coordinates to second texture unit.
vb.setTexCoords(1, tunnelTextureArray, 0.0004f, null);
// Load texture image ...
tunnelTextureImage2 = new Image2D(Image2D.RGB, loadImage("/ttex2.png"));
// Create texmap
tunnelTexture2 = new Texture2D(tunnelTextureImage2);
// Choose blending mode for the texture layer, additive by default
tunnelTexture2.setBlending(Texture2D.FUNC_ADD);
}
// Backup first texture reference...
tunnelTexture1 = ap.getTexture(0);
// Update the textures...
switchTunnelMode(1);
// Create linear fog for the tunnel
tunnelFog = new Fog();
tunnelFog.setMode(Fog.LINEAR);
tunnelFog.setColor(0x006080a0);
tunnelFog.setLinear(10.0f, 25.0f);
}
//
private void updateTunnelScene(int time, int delta)
{
//
World scn = m_scenes[SCENE_TUNNEL];
// Find the omni light
Light l = (Light) scn.find(UID_TUNNEL_LIGHT);
// Set the light's intensity
l.setIntensity(m_lightIntensity);
/** Fade out mode */
if (m_tunnelFadeOut)
{
if (DEBUG)
System.out.println(delta);
// Drop intensity
m_lightIntensity-=(delta * 0.001f);
// Fade below zero.. Looks like we have ambient light somewhere?
if (m_lightIntensity <= -2.0f)
{
//
freeOldScene();
//
m_scenes[SCENE_POND] = loadScene("/pond_vilkutus2.m3g");
preInitPondScene();
//
m_currentScene = SCENE_POND;
m_currentTime = 0;
}
}
}
// Nulls references to objects which we found when initializing the tunnel.
// This makes them available for garbage collection.
private void removeTunnelScene()
{
tunnelTextureImage2 = null;
tunnelFog = null;
tunnelTexture1 = null;
tunnelTexture2 = null;
tunnelTextureArray = null;
tunnelTexCoords = null;
}
// Switches between different texture depths
private void switchTunnelMode(int tnlMode)
{
// Select the world...
World w = m_scenes[SCENE_TUNNEL];
// Find the tunnel mesh
Mesh tnl = (Mesh) w.find(UID_TUNNEL_MESH);
// Get the appearance from the mesh
Appearance ap = tnl.getAppearance(0);
// remove textures?
if (tnlMode == NO_TEXTURE)
{
ap.setTexture(0, null);
// We must always check before using texture unit 1.
if(numTextureUnits>1)
ap.setTexture(1, null);
}
else
if (tnlMode == ONE_TEXTURE)
{
ap.setTexture(0, tunnelTexture1);
// We must always check before using texture unit 1.
if(numTextureUnits>1)
ap.setTexture(1, null);
}
else
if (tnlMode == DUAL_TEXTURE)
{
ap.setTexture(0, tunnelTexture1);
// We must always check before using texture unit 1.
// Note that on an implementation with only 1 texture unit,
// this is the same as ONE_TEXTURE mode.
if(numTextureUnits>1)
ap.setTexture(1, tunnelTexture2);
}
else
// Switch fog on/off
if (tnlMode == TOGGLE_FOG)
{
if (!m_fogOn)
{
ap.setFog(tunnelFog);
m_fogOn = true;
}
else
{
ap.setFog(null);
m_fogOn = false;
}
}
}
// Picks some cameras etc
private void preInitPondScene()
{
//
World pond = m_scenes[SCENE_POND];
// Default to first camera
Camera c = (Camera) pond.find(UID_POND_CAMERA1);
c.setPerspective(m_cameraFOVs[0], 1.0f, 0.1f,5);
//
m_currentCamera = 0;
pond.setActiveCamera(c);
// Target camera to the ant. Note that the y target axis is scene's z-axis because
// the scene is exported from 3dsmax, in which z points up on world space
// For this reason, it is more convenient to align the group in which the camera
// is enclosed, rather than the camera itself. We rotate the camera 180 degrees
// (using a scale) because alignment aligns the positive Z axis, and the camera
// looks along the negative Z axis. If we do not do this, then the camera will
// alway look *away* from the target, instead of towards it.
Node n = (Node) pond.find(UID_POND_ANTHEAD);
c.getParent().setAlignment(n, n.ORIGIN, pond, pond.Z_AXIS);
c.scale(-1, 1, -1);
// Set field-of-view and clip params by hand
c = (Camera) pond.find(UID_POND_CAMERA2);
c.setPerspective(m_cameraFOVs[1], 1.0f, 0.1f,5);
c.getParent().setAlignment(n, Node.ORIGIN, pond, Node.Z_AXIS);
c.scale(-1, 1, -1);
c = (Camera) pond.find(UID_POND_CAMERA3);
c.setPerspective(m_cameraFOVs[2], 1.0f, 0.1f,5);
c.getParent().setAlignment(n, Node.ORIGIN, pond, Node.Z_AXIS);
c.scale(-1, 1, -1);
c = (Camera) pond.find(UID_POND_CAMERA4);
c.setPerspective(m_cameraFOVs[3], 1.0f, 0.1f,5);
c.getParent().setAlignment(n, Node.ORIGIN, pond, Node.Z_AXIS);
c.scale(-1, 1, -1);
}
// Loads an image
private Image loadImage(String name)
{
try
{
return Image.createImage(name);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
// Inits some snowflakes for the Nokia scene
private void initSnowFlakes()
{
// First we init a vertex array with 3 components (X,Y,Z), size of each component is byte
flakeVertexArray = new VertexArray(flakeVertices.length / 3, 3, 2);
// Now, we copy the actual XYZ coordinates to the array
flakeVertexArray.set(0, flakeVertices.length / 3, flakeVertices);
// Init a texture coordinate array with same size as the coordinate array, but only two coords for each vertex (u,v)
flakeTextureArray = new VertexArray(flakeTexCoords.length / 2, 2, 2);
// Copy actual values again
flakeTextureArray.set(0, flakeTexCoords.length / 2, flakeTexCoords);
// Next we need to create a vertex buffer, to which we'll assign the texture coordinates and XYZ coordinates
flakeVertexBuffer = new VertexBuffer();
// No scale, no bias in XYZ coordinates
flakeVertexBuffer.setPositions(flakeVertexArray, 0.01f, null);
// Assign texture coordinates to first texture unit. Again, no scale & no bias is needed
flakeVertexBuffer.setTexCoords(0, flakeTextureArray, 0.1f, null);
// Next we need to create a triangle strip array which holds the polygon definitions for the flakes
flakeTriangles = new TriangleStripArray(flakeStrip, flakeStripLengths);
/**
*
* We could also create the triangle strip implicitly, by defining the first vertex index as zero..
* This saves some space when simple, continuous triangle strips are created.
*
* flakeTriangles = new TriangleStripArray(0, flakeStripLengths);
*
*/
// First we need to create new appearance
flakeAppearance = new Appearance();
// Then we load a texture image ... We need to use alpha due to transparent pixels
flakeTextureImage = new Image2D(Image2D.RGBA, loadImage("/snowflake.png"));
// Then we create a texture map from the image
flakeTexture = new Texture2D(flakeTextureImage);
// Choose worst possible filtering type to gain more speed (actually it's already selected by default)
flakeTexture.setFiltering(Texture2D.FILTER_BASE_LEVEL, Texture2D.FILTER_NEAREST);
// Just replace the texel directly with the source for more speed
flakeTexture.setBlending(Texture2D.FUNC_REPLACE);
// Next, create a polygon mode definition
flakePolyMode = new PolygonMode();
// No, we don't need perspective correction for such small polygons
flakePolyMode.setPerspectiveCorrectionEnable(false);
// Shading should apply to whole polygon
flakePolyMode.setShading(PolygonMode.SHADE_FLAT);
// Disable visible side culling (both sides of flakes are seen)
flakePolyMode.setCulling(PolygonMode.CULL_NONE);
// Define winding as clockwise (actually it doesn't matter here since no culling is used...)
flakePolyMode.setWinding(PolygonMode.WINDING_CW);
// No, we don't want the flakes to be lit by camera light
flakePolyMode.setLocalCameraLightingEnable(false);
// Sincle no culling is used, we need to light both sides of the polygon
flakePolyMode.setTwoSidedLightingEnable(true);
// Let's define how the polygon is blended with the background
flakeCompositing = new CompositingMode();
// We want to use the alpha to blend the pixels to background
flakeCompositing.setBlending(CompositingMode.ALPHA);
// Don't write anything to alpha buffer
flakeCompositing.setAlphaWriteEnable(false);
// Set the texture map to the appearance's first texture unit
flakeAppearance.setTexture(0, flakeTexture);
// Assign the polygon mode to the appearance
flakeAppearance.setPolygonMode(flakePolyMode);
// Assign the compositing mode to the appearance
flakeAppearance.setCompositingMode(flakeCompositing);
// Get the world..
World nokia = m_scenes[SCENE_NOKIA];
// Finally, let's do some meshes from these definitions and add them to the scene
m_snowFlakes = new Mesh[NUM_SNOWFLAKES];
//
for (int a = 0; a < NUM_SNOWFLAKES; a++)
{
m_snowFlakes[a] = new Mesh(flakeVertexBuffer, flakeTriangles, flakeAppearance);
m_snowFlakes[a].translate(
rnd(-SNOWFLAKE_SCALE, SNOWFLAKE_SCALE),
rnd(-SNOWFLAKE_SCALE, SNOWFLAKE_SCALE),
rnd(GROUND_LEVEL, GROUND_LEVEL + (SNOWFLAKE_SCALE/2.0f))
);
nokia.addChild(m_snowFlakes[a]);
}
}
// Removes references to snowflake objects. These will then be garbage collected.
private void removeSnowFlakes()
{
flakeAppearance = null;
flakeMaterial = null;
flakePolyMode = null;
flakeCompositing = null;
flakeTextureImage = null;
flakeTexture = null;
flakeVertexArray = null;
flakeTextureArray = null;
flakeVertexBuffer = null;
flakeTriangles = null;
m_snowFlakes = null;
}
//
private float rnd(float min, float max)
{
float p = (float) (m_random.nextInt() & 0xFFF) / 4095.0f;
float q = 1.0f - p;
return p * max + q * min;
}
// Animates the snowflakes...
private void animateSnowFlakes(int time)
{
float[] xyz = new float[3];
for (int a = 0; a < NUM_SNOWFLAKES; a++)
{
// push the new position to the flake. Note that the scene is exported from 3dsmax, thus z points up.
m_snowFlakes[a].translate(0,0, -0.1f);
// get current snowflake position
m_snowFlakes[a].getTranslation(xyz);
// move the flakes a bit
if (xyz[2] < GROUND_LEVEL)
{
// push the new position to the flake
m_snowFlakes[a].translate(0,0, SNOWFLAKE_SCALE/2.0f);
}
}
}
// Definitions for a snowflake
private Appearance flakeAppearance;
private Material flakeMaterial;
private PolygonMode flakePolyMode;
private CompositingMode flakeCompositing;
private Image2D flakeTextureImage;
private Texture2D flakeTexture;
// Arrays & buffers for snowflake
private VertexArray flakeVertexArray;
private VertexArray flakeTextureArray;
private VertexBuffer flakeVertexBuffer;
private TriangleStripArray flakeTriangles;
// Meshes
private Mesh[] m_snowFlakes;
// Vertex coordinates for a snowflake (a simple flat quad actually)
private static final short flakeVertices[] =
{
(short) -10, (short) 0, (short) 10,
(short) -10, (short) 0, (short) -10,
(short) 10, (short) 0, (short) 10,
(short) 10, (short) 0, (short) -10
};
// Texture coordinates for the snowflake
private static final short flakeTexCoords[] =
{
(short) 0, (short) 10,
(short) 0, (short) 0,
(short) 10, (short) 10,
(short) 10, (short) 0,
};
// Strip lengths for a simple snowflake
private static final int flakeStripLengths[] = { 4 };
// Triangle strip for the snowflake
private static final int flakeStrip[] =
{
0, 1, 2, 3
};
// State for tunnel scene
private int numTextureUnits;
private Image2D tunnelTextureImage2;
//
private Fog tunnelFog;
//
private Texture2D tunnelTexture1;
private Texture2D tunnelTexture2;
// Arrays & buffers for the tunnel
private VertexArray tunnelTextureArray;
// Texture coordinates for the tunnel
private short[] tunnelTexCoords;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -