Android Open Source - Schooner-3D Engine






From Project

Back to project page Schooner-3D.

License

The source code is released under:

Apache License

If you think the Android project Schooner-3D listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2012 Dan Mercer//from w  w w  .  j a v  a2  s  . c o  m
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.supermercerbros.gameengine.engine;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

import android.util.FloatMath;
import android.util.Log;

import com.supermercerbros.gameengine.collision.CollisionDetector;
import com.supermercerbros.gameengine.collision.OnCollisionCheckFinishedListener;
import com.supermercerbros.gameengine.engine.shaders.Material;
import com.supermercerbros.gameengine.objects.GameObject;
import com.supermercerbros.gameengine.objects.Metadata;
import com.supermercerbros.gameengine.util.LoopingThread;
import com.supermercerbros.gameengine.util.Toggle;

/**
 * Handles the interactions of game elements in the world space.
 * 
 * @version 1.0
 */
public class Engine extends LoopingThread {
  private static final String TAG = "Engine";

  /**
   * To be used by subclasses of Engine. Contains the GameObjects currently in
   * the Engine.
   */
  protected final LinkedList<GameObject> objects;
  private boolean aBufs = true;
  private final Camera cam;
  private final CollisionDetector cd;
  
  private final Toggle cdIsFinished = new Toggle(false);
  // Be careful to always synchronize access of these fields:
  private final Light light = new Light();
  
  private Scene newScene;
  
  private final RenderData outA;
  private final RenderData outB;
  
  private final DataPipe pipe;
  
  private Scene scene;
  private long time;

  /**
   * @param pipe
   *            The DataPipe that this Engine will use to communicate with the
   *            renderer and UI threads.
   * @param cam
   *            A pointer to the Camera object that will be used by the Game
   *            Engine.
   */
  public Engine(DataPipe pipe, Camera cam) {
    super("Schooner3D Engine thread");
    Log.d(TAG, "Constructing Engine...");
    this.pipe = pipe;
    this.cam = cam;
    this.objects = new LinkedList<GameObject>();
    
    final OnCollisionCheckFinishedListener listener = new OnCollisionCheckFinishedListener() {
      @Override
      public void onCollisionCheckFinished() {
        synchronized (cdIsFinished) {
          cdIsFinished.setState(true);
          cdIsFinished.notify();
        }
      }
    };
    this.cd = new CollisionDetector(listener);
    
    outA = new RenderData(0, pipe.VBO_capacity / 4, pipe.IBO_capacity / 2);
    outB = new RenderData(1, pipe.VBO_capacity / 4, pipe.IBO_capacity / 2);
    
    Log.d(TAG, "Engine constructed.");
  }
  
  /**
   * Adds the collection of GameObjects to the Engine
   * 
   * @param objects
   */
  public void addAllObjects(Collection<GameObject> objects) {
    if (!started) {
      this.objects.addAll(objects);
      for (final GameObject object : objects) {
        if (object.getBounds() != null) {
          cd.addCollider(object);
        }
        outA.modelMatrices.add(new float[16 + (16 * object
            .getExtraMatrixCount())]);
        outB.modelMatrices.add(new float[16 + (16 * object
            .getExtraMatrixCount())]);
      }
    } else {
      throw new IllegalStateException("Do not add GameObjects to the Engine while it is running.");
    }
  }
  
  /**
   * Adds the given GameObject to the Engine
   * 
   * @param object
   */
  public void addObject(GameObject object) {
    if (!started) {
      objects.add(object);
      if (object.getBounds() != null) {
        cd.addCollider(object);
      }
      outA.modelMatrices.add(new float[16 + (16 * object
          .getExtraMatrixCount())]);
      outB.modelMatrices.add(new float[16 + (16 * object
          .getExtraMatrixCount())]);
    } else {
      throw new IllegalStateException("Do not add GameObjects to the Engine while it is running.");
    }
  }
  
  @Override
  public void end() {
    super.end();
    cd.end();
  }
  
  /**
   * Removes the given GameObject from the Engine. TODO remove this?
   * 
   * @param object
   */
  public void removeObject(GameObject object) {
    if (!started) {
      final int index = objects.indexOf(object);
      objects.remove(object);
      outA.modelMatrices.remove(index);
      outB.modelMatrices.remove(index);
    } else {
      throw new IllegalStateException("Do not remove GameObjects from the Engine while it is running.");
    }
  }
  
  /**
   * Sets the directional light of the scene. The given xyz coordinates do not need to be normalized.
   * 
   * @param x
   *            The x-coordinate of the light vector
   * @param y
   *            The x-coordinate of the light vector
   * @param z
   *            The x-coordinate of the light vector
   * @param r
   *            The red value of the light's color
   * @param g
   *            The green value of the light's color
   * @param b
   *            The blue value of the light's color
   */
  public void setLight(float x, float y, float z, float r, float g, float b) {
    final float length = FloatMath.sqrt(x*x + y*y + z*z);
    x /= length;
    y /= length;
    z /= length;
    synchronized (light) {
      light.x = x;
      light.y = y;
      light.z = z;
      light.r = r;
      light.g = g;
      light.b = b;
    }
  }
  
  public void setScene(Scene scene) {
    if (scene == null) {
      throw new NullPointerException("scene cannot be null, try NullScene for debugging");
    }
    if (!started) {
      this.scene = scene;
      scene.loadObjects(this);
    } else {
      synchronized(this) {
        this.newScene = scene;
      }
    }
  }
  
  /* (non-Javadoc)
   *  Sets time to System.currentTimeMillis() for first iteration
   */
  @Override
  public void start() {
    if (this.scene == null) {
      throw new IllegalStateException("Engine.setScene() has not been called.");
    }
    time = System.currentTimeMillis();
    super.start();
  }
  
  @Override
  protected void loop() {
    // Change scene if necessary
    synchronized (this) {
      if (newScene != null) {
        this.scene = newScene;
        newScene = null;
        objects.clear();
        scene.loadObjects(this);
      }
    }
    
    cd.go(); // Start collision detection (in background)
    
    // While collision detection is running
    scene.onBeginFrame(time);
    for (GameObject object : objects) {
      object.drawVerts(time);
    }
    cam.update(time);
    
    waitOnToggle(cdIsFinished, true); // Wait for collision detection
    
    // After collision detection has finished
    scene.onCollisionDetectorFinished();
    for (GameObject object : objects) {
      object.drawMatrix(time);
    }
    
    // Swap RenderData
    final RenderData out;
    if (aBufs) {
      out = outA;
    } else {
      out = outB;
    }
    
    // Update pipe
    final int outIndexOffset = out.index * 2;
    out.primitives.clear();
    
    final Iterator<float[]> matrixIter = out.modelMatrices.iterator();
    int vOffset = 0, iOffset = 0;
    for (GameObject object : objects) {
      final Metadata objData = object.info;
      final int[] objBufferLocations = objData.bufferLocations;
      final Material objMaterial = objData.mtl;
      
      synchronized (object) {
        if (object.isVisible()) {
          final boolean vertsAreDirty = objBufferLocations[outIndexOffset] == -1;
          final boolean indicesAreDirty = objBufferLocations[outIndexOffset + 1] == -1;
          
          // Load verts
          if (vertsAreDirty) {
            final int rangeStart = vOffset;
            objBufferLocations[outIndexOffset] = rangeStart;
            if (object.isInstance) {
              final GameObject objParent = object.parent;
              vOffset += objParent.info.mtl.loadObjectToVBO(objParent, out.vbo, vOffset);
            } else {
              vOffset += objMaterial.loadObjectToVBO(object,
                  out.vbo, vOffset);
            }
            out.vboRange.include(rangeStart, vOffset);
          } else {
            vOffset = objBufferLocations[outIndexOffset] + objData.count * objMaterial.getStride();
          }
          
          // Load indices
          final int size = objData.size;
          if (indicesAreDirty) {
            final int rangeStart = iOffset;
            System.arraycopy(object.indices, 0, out.ibo, iOffset, size);
            objBufferLocations[outIndexOffset + 1] = iOffset;
            iOffset += size;
            out.iboRange.include(rangeStart, iOffset);
          } else {
            iOffset = objBufferLocations[outIndexOffset + 1] + size;
          }
          
          // Load matrices
          object.writeMatrices(matrixIter.next());
          
          out.primitives.add(objData);
        }
      }
    }
    
    cam.writeToArray(out.viewMatrix, 0);
    
    synchronized (light) {
      light.copyTo(out.light);
    }
    
    time = pipe.putData(this, out);
    aBufs = !aBufs;
//    LoopLog.i(TAG, "Engine is switching to RD " + (aBufs ? 0 : 1));
  }
  
  @Override
  protected void onBegin() {
    scene.onBegin();
  }
  
  @Override
  protected void onEnd() {
    Log.i(TAG, "Engine end.");
  }
  
  @Override
  protected void onPause() {
    Time.INSTANCE.pause();
  }
  
  @Override
  protected void onResume() {
    Time.INSTANCE.resume();
  }
}




Java Source Code List

com.supermercerbros.gameengine.GameActivity.java
com.supermercerbros.gameengine.GameView.java
com.supermercerbros.gameengine.Schooner3D.java
com.supermercerbros.gameengine.TestActivity.java
com.supermercerbros.gameengine.TestMaterials.java
com.supermercerbros.gameengine.TestObjects.java
com.supermercerbros.gameengine.animation.AnimationData.java
com.supermercerbros.gameengine.animation.Keyframe.java
com.supermercerbros.gameengine.animation.MeshAnimation.java
com.supermercerbros.gameengine.armature.ActionData.java
com.supermercerbros.gameengine.armature.Action.java
com.supermercerbros.gameengine.armature.BinarySkeletalVertexModifier.java
com.supermercerbros.gameengine.armature.Bone.java
com.supermercerbros.gameengine.armature.SkeletalVertexModifier.java
com.supermercerbros.gameengine.armature.Skeleton.java
com.supermercerbros.gameengine.collision.Bounds.java
com.supermercerbros.gameengine.collision.Collider.java
com.supermercerbros.gameengine.collision.CollisionDetector.java
com.supermercerbros.gameengine.collision.Collision.java
com.supermercerbros.gameengine.collision.DebugListener.java
com.supermercerbros.gameengine.collision.Edge.java
com.supermercerbros.gameengine.collision.Face.java
com.supermercerbros.gameengine.collision.Feature.java
com.supermercerbros.gameengine.collision.Intersection.java
com.supermercerbros.gameengine.collision.Line.java
com.supermercerbros.gameengine.collision.LocalDistMinimum.java
com.supermercerbros.gameengine.collision.Matrix.java
com.supermercerbros.gameengine.collision.OnCollisionCheckFinishedListener.java
com.supermercerbros.gameengine.collision.Plane.java
com.supermercerbros.gameengine.collision.Point.java
com.supermercerbros.gameengine.collision.Polyhedron.java
com.supermercerbros.gameengine.collision.SphereBounds.java
com.supermercerbros.gameengine.collision.Vector.java
com.supermercerbros.gameengine.collision.Vertex.java
com.supermercerbros.gameengine.debug.JankCatcher.java
com.supermercerbros.gameengine.debug.LoopLog.java
com.supermercerbros.gameengine.engine.Camera.java
com.supermercerbros.gameengine.engine.DataPipe.java
com.supermercerbros.gameengine.engine.EGLContextLostHandler.java
com.supermercerbros.gameengine.engine.Engine.java
com.supermercerbros.gameengine.engine.GameRenderer.java
com.supermercerbros.gameengine.engine.Light.java
com.supermercerbros.gameengine.engine.Normals.java
com.supermercerbros.gameengine.engine.RenderData.java
com.supermercerbros.gameengine.engine.Scene.java
com.supermercerbros.gameengine.engine.Time.java
com.supermercerbros.gameengine.engine.shaders.Material.java
com.supermercerbros.gameengine.engine.shaders.Program.java
com.supermercerbros.gameengine.engine.shaders.ShaderLib.java
com.supermercerbros.gameengine.engine.shaders.Shader.java
com.supermercerbros.gameengine.engine.shaders.VertexModifier.java
com.supermercerbros.gameengine.handlers.OnAnimationCompleteDispatcher.java
com.supermercerbros.gameengine.handlers.OnAnimationCompleteListener.java
com.supermercerbros.gameengine.hud.CoordsConverter.java
com.supermercerbros.gameengine.hud.GameHud.java
com.supermercerbros.gameengine.hud.HudElement.java
com.supermercerbros.gameengine.material.CelShadedMaterial.java
com.supermercerbros.gameengine.material.TexturedMaterial.java
com.supermercerbros.gameengine.math.BezierCurve.java
com.supermercerbros.gameengine.math.Curve.java
com.supermercerbros.gameengine.math.MatrixUtils.java
com.supermercerbros.gameengine.math.Quaternion.java
com.supermercerbros.gameengine.motion.CurveMovement.java
com.supermercerbros.gameengine.motion.MovementData.java
com.supermercerbros.gameengine.motion.Movement.java
com.supermercerbros.gameengine.objects.AnimatedMeshObject.java
com.supermercerbros.gameengine.objects.BasicMaterial.java
com.supermercerbros.gameengine.objects.BonedObject.java
com.supermercerbros.gameengine.objects.GameObject.java
com.supermercerbros.gameengine.objects.Metadata.java
com.supermercerbros.gameengine.parsers.ConstantCurve.java
com.supermercerbros.gameengine.parsers.GameFactory.java
com.supermercerbros.gameengine.parsers.PreBoneData.java
com.supermercerbros.gameengine.parsers.PreObjectData.java
com.supermercerbros.gameengine.parsers.Sch3D.java
com.supermercerbros.gameengine.render.Compositor.java
com.supermercerbros.gameengine.shaders.ProgramSource.java
com.supermercerbros.gameengine.texture.BitmapTexture.java
com.supermercerbros.gameengine.texture.ETC1CompressedTexture.java
com.supermercerbros.gameengine.texture.Texture.java
com.supermercerbros.gameengine.util.BetterDataInputStream.java
com.supermercerbros.gameengine.util.DelayedRunnable.java
com.supermercerbros.gameengine.util.GLES2.java
com.supermercerbros.gameengine.util.IPO.java
com.supermercerbros.gameengine.util.LoopingThread.java
com.supermercerbros.gameengine.util.Toggle.java
com.supermercerbros.gameengine.util.Utils.java