// 3D Engine // // Universe which contains all objects // // Author Matthew Caryl // Created 5.5.97 // // Although under copywrite to the author (Matthew Caryl) this code can be copied and modified for non-commercial // purposes as long as any derivatives contain this condition. package ADT; import java.awt.Graphics; import java.awt.Color; public class Universe { // // Public interface // public Universe(int width, int height, Camera camera, Light light) { universe_width = width; universe_height = height; camera_entity = camera; light_entity = light; light_entity.setUniverse(this); } public void addEntity(Entity entity) { if (number_entities >= entity_list.length) { Entity[] entities = new Entity[2 * entity_list.length]; for (int i = entity_list.length - 1; i >= 0; i--) entities[i] = entity_list[i]; entity_list = entities; } entity_list[number_entities] = entity; number_entities++; entity.light(light_vector); } public void addEntity(Entity[] entities) { for (int i = entities.length - 1; i >= 0; i--) addEntity(entities[i]); } public void subEntity(Entity entity) { for (int i = number_entities - 1; i >= 0; i--) if (entity_list[i] == entity) { for (int j = i + 1; j < number_entities; j++) entity_list[j - 1] = entity_list[j]; number_entities--; return; } System.err.println("could not remove entity"); } public void subEntity(Entity[] entities) { for (int i = entities.length - 1; i >= 0; i--) subEntity(entities[i]); } public void clear(Graphics graphics, Color color) { graphics.setColor(color); graphics.fillRect(0, 0, universe_width, universe_height); } public void render(Graphics graphics) { int number_triangles = 0; camera_entity.perspective(view_transform); try { for (int i = number_entities - 1; i >= 0; i--) { entity_list[i].view(view_transform); number_triangles = entity_list[i].listTriangles(triangle_list, number_triangles); } } catch (ArrayIndexOutOfBoundsException e) { triangle_list = new Triangle[2 * triangle_list.length]; render(graphics); return; } sortTriangles(0, number_triangles - 1); graphics.translate(universe_width / 2, universe_height / 2); for (int i = number_triangles - 1; i >= 0; i--) triangle_list[i].draw(graphics, display_xs, display_ys, ambient_light, diffuse_light); graphics.translate(-universe_width / 2, -universe_height / 2); } // // Package interface // void relight(Vector light, float ambient, float diffuse) { light_vector = light; ambient_light = ambient; diffuse_light = diffuse; for (int i = number_entities - 1; i >= 0; i--) entity_list[i].light(light_vector); } // // Private interface // private int universe_width; private int universe_height; private Camera camera_entity; private Light light_entity; private Entity[] entity_list = new Entity[1]; private int number_entities = 0; private Triangle[] triangle_list = new Triangle[100]; private int[] display_xs = new int[3]; private int[] display_ys = new int[3]; private Matrix view_transform = new Matrix(); private Vector light_vector; private float ambient_light; private float diffuse_light; private void sortTriangles(int m, int n) { if ((n - m) > 1) { Triangle c = triangle_list[m]; int j = m + 1; int k = n; while (j < k) { if (triangle_list[j].aheadTriangle(c)) j++; else if (c.aheadTriangle(triangle_list[k])) k--; else { Triangle t = triangle_list[j]; triangle_list[j] = triangle_list[k]; triangle_list[k] = t; j++; k--; } } triangle_list[m] = triangle_list[j - 1]; triangle_list[j - 1] = c; sortTriangles(m, j - 1); sortTriangles(j, n); } } }