TheBennyBox Engine - Performance Friendly Instanced Static Meshes Like In UE4 - java

I'm using the java game engine made by thebennybox to create my own engine. Previously I worked with UE4 where you could have Static Mesh Actors, in his engine this would probably be a GameObject with a MeshRenderer component attached to it:
GameObject staticMeshActor_Grass = new GameObject();
AddObject(staticMeshActor_Grass.addComponent(new MeshRenderer(
new Mesh("plane.obj"), new Material(
new Texture("T_Grass_BC.png"), 1, 8,
new Texture("T_Grass_N.png")))));
Now I'm trying to create a large field of these grass tiles but since these are all their individual GameObjects (or Actors in UE4 terms) after 16x16 tiles it starts to cripple the frame rate!
I believe I can solve this problem if I make instances of multiple static meshes inside one GameObject in order to make it performance friendly. In UE4 this feature is called 'Instanced Static Mesh Component' which allows for that and I would like to have something similar.
Here's the GameObject class made by thebennybox:
public class GameObject
{
private ArrayList<GameObject> m_children;
private ArrayList<GameComponent> m_components;
private Transform m_transform;
private CoreEngine m_engine;
public GameObject()
{
m_children = new ArrayList<GameObject>();
m_components = new ArrayList<GameComponent>();
m_transform = new Transform();
m_engine = null;
}
public GameObject AddChild(GameObject child)
{
m_children.add(child);
child.SetEngine(m_engine);
child.GetTransform().SetParent(m_transform);
return this;
}
public GameObject AddComponent(GameComponent component)
{
m_components.add(component);
component.SetParent(this);
return this;
}
public void InputAll(float delta)
{
Input(delta);
for(GameObject child : m_children)
child.InputAll(delta);
}
public void UpdateAll(float delta)
{
Update(delta);
for(GameObject child : m_children)
child.UpdateAll(delta);
}
public void RenderAll(Shader shader, RenderingEngine renderingEngine)
{
Render(shader, renderingEngine);
for(GameObject child : m_children)
child.RenderAll(shader, renderingEngine);
}
public void Input(float delta)
{
m_transform.Update();
for(GameComponent component : m_components)
component.Input(delta);
}
public void Update(float delta)
{
for(GameComponent component : m_components)
component.Update(delta);
}
public void Render(Shader shader, RenderingEngine renderingEngine)
{
for(GameComponent component : m_components)
component.Render(shader, renderingEngine);
}
public ArrayList<GameObject> GetAllAttached()
{
ArrayList<GameObject> result = new ArrayList<GameObject>();
for(GameObject child : m_children)
result.addAll(child.GetAllAttached());
result.add(this);
return result;
}
public Transform GetTransform()
{
return m_transform;
}
public void SetEngine(CoreEngine engine)
{
if(this.m_engine != engine)
{
this.m_engine = engine;
for(GameComponent component : m_components)
component.AddToEngine(engine);
for(GameObject child : m_children)
child.SetEngine(engine);
}
}
}
The AddObject() method shown in the first part comes from an abstract class and eventually calls the method AddChild(GameObject child) inside the GameObject class. As you can see we have an ArrayList of GameObjects and GameComponents. Now I would have to implement some method in order to support the creation of multiple mesh instances inside one GameObject.
I've already tried to add multiple MeshRenderer components to one GameObject but this didn't work out. Maybe someone has a suggestion how I might go about this?
if you're really interested and want to help me you can download the engine here: https://github.com/BennyQBD/3DGameEngine
Just use 'Open Projects From File System..' in eclipse, choose the directory of this folder and once you've done that you should be able to run the program.
Thanks a lot for your help!

this might be what you are looking for:
http://www.java-gaming.org/topics/issues-with-batching-meshes/37809/view.html
They mention that ThinMatrix has created a tutorial about instancing meshes, hope this helps you!

Related

How to implement chain of responsibility with Java Swing

I have the task of creating a simple drawing app, where one can draw basic shapes (ovals,lines,rectangles) with border and fill colors of choice, using Java Swing and MVC.
The shapes part of the model is implemented using the composite pattern. The functionality to be implementing is drawing (this is already handled by the shapes classes themselves), resizing, moving and deleting shapes and I am supposed to use chain of responsibility (CoR) pattern to accomplish this.
CoR makes sense to me in theory, but I have difficulty grasping how I can apply it for implementing the functionality in practice. I understand that when I click on the drawing panel the program should recognize which shape is selected and then I can implement the methods for resizing,moving,deleting.
So what I need advice on is:
1) how to practically implement CoR pattern here?
2) what is a good way to implement the functionality for resizing, moving, deleting? In own concrete handler classes, as methods in the shapes classes, other?
Many thanks for help.
Here is a proposed basic implementation of CoR.
For ease of use the following code is a one-file mre : the entire code can be copy-pasted into ShapeManipulator.java and run:
public class ShapeManipulator {
public static void main(String[] args) {
Shape s1 = new Shape();
Shape s2 = new Shape();
Shape s3 = new Shape();
ShapeManipulationBase move = new MoveHandler();
ShapeManipulationBase resize = new ResizeHandler();
ShapeManipulationBase delete = new DeleteHandler();
move.setXparam(50).setYparam(25).handle(s1);
resize.setXparam(100).setYparam(250).handle(s1);
resize.setXparam(200).setYparam(20).handle(s2);
delete.handle(s3);
}
}
//CoR basic interface
interface ShapeManipulationHandler {
void handle(Shape shape);
}
//base class allows swtting of optional x, y parameters
abstract class ShapeManipulationBase implements ShapeManipulationHandler {
protected int Xparam, Yparam;
//setters return this to allow chaining of setters
ShapeManipulationBase setXparam(int xparam) {
Xparam = xparam;
return this;
}
ShapeManipulationBase setYparam(int yparam) {
Yparam = yparam;
return this;
}
#Override
public abstract void handle(Shape shape) ;
}
class MoveHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Moving "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
}
}
class ResizeHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Resizing "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
}
}
class DeleteHandler extends ShapeManipulationBase {
#Override
public void handle(Shape shape) {
System.out.println("Deleting "+ shape);
}
}
class Shape{
private static int shapeCouner = 0;
private final int shapeNumber;
Shape() {
shapeNumber = ++shapeCouner;
}
#Override
public String toString() {
return "Shape # "+shapeNumber;
}
}

Create Subclass and after super() call remove unnecessary items from parent

I have in my app 2 bars : topBar, bottomBar.
Basically each one of them creates images and set there positions on the screen. in my app I added a new screen that suppose to be with different bar - Advanced, but with some identical logic.
public class TopBar {
public TopBar () {
initImageA();
initImageB();
initResultManager();
initBG();
initLines()
}
}
public class BottomBar {
public BottomBar () {
initBg();
initBox();
initCover();
initcolorsLine();
initMenu()
}
}
In my app I crate bar according to the state:
private TopBar mTopBar;
private Bottom mBottomBar;
if (mState == "normal"){
mTopBar = new TopBar();
mBottomBar = new Bottom();
}
else {
mTopBar = new AdvancedTopBar();
mBottomBar = new AdvancedBottomBar();
}
mTopBar.setTitle()
mTopBar.setMainImage();
mBottomBar.drawLines()
.
.
.
AdvancedTopBar
public class AdvancedTopBar extends TopBar {
public AdvancedTopBar () {
super();
removeImageA();
removeImageB();
removeResultManager();
removeBG();
removeLines();
}
private removeImageA() {
.
.
.
}
}
Is it the right way to use inherence for creating the AdvancedTopBar for some identical logic (3,4 members) and calling to parent super() whats triggers initializing of images and then I just remove them one by one and create my own images, I think it's wrong... what options do I have to use different types of bars by on instance?
Just one of the many possible approaches: have one class and pass a boolean switch value in the constructor.
public class TopBar {
public TopBar(boolean advanced) {
doCommonStuff();
if (advanced) {
doAdvancedStuff();
}
}
}
So new TopBar(true) will give you an advanced bar, new TopBar(false) a standard one.

Synchronizing events / data in java swing between many different classes

My question is conceptual about synchronizing data and events in programming a gui. (This example shows batch state being the facilitator of taking classes that implement the same interface and dynamical updating cells in two different frames.This code is where I got my idea. )
I am assuming that I will create new instances of this batch state object specifically in the classes where an event is triggered(panel) and the reaction to that event(another panel) . I will do this by adding the classes that need to communicate to the a list of bsListeners. Then call the batch state function like "setSelectedCell()" to iterate over each class to synchronize them.
The Problem
This would work perfect if the object both shared the same arrayList but since they are both new instances they don't. I tried changing things to static and it is freaking out especially in the interface. Is this approach logical I am brand new to programming gui's? Sorry this is a novel.
interface BatchStateListener {
public void valueChanged(Cell cell, String newValue);
public void selectedCellChanged(Cell newSelectedCell)
}
class BatchState {
private String[][] values;
private Cell selectedCell;
private List<BatchStateListener> listeners;
public BatchState(int records, int fields) {
values = new String[records][fields];
selectedCell = null;
listeners = new ArrayList<BatchStateListener>();
}
public void addListener(BatchStateListener l) {
listeners.add(l);
}
public void setValue(Cell cell, String value) {
values[cell.record][cell.field] = value;
for (BatchStateListener l : listeners) {
l.valueChanged(cell, value);
}
}
public String getValue(Cell cell) {
return values[cell.record][cell.field];
}
public void setSelectedCell(Cell selCell) {
selectedCell = selCell;
for (BatchStateListener l : listeners) {
l.selectedCellChanged(selCell);
}
}
public Cell getSelectedCell() {
return selectedCell;
}
}
My questions was a bit confusing, but I came to my answer. I was just wondering how to implement this BatchState class in my code. I found that if I make it in main and pass it to the constructors frames/panels that need to communicate with each other they all can share reference to it.

Calling a method from JFrame from another class

I am currently making a terrain generator, everything works fine in one class but I am going to be expanding my application.
Currently I have a JFrame class which holds everything, generating the terrain, painting the terrain, finding locations etc.
I want to add another class that will generate the terrain but when I create this class I need to access fields from the main JFrame class and when I do I get a stack overflow error - here is my code.
public class Simulator extends Applet
{
//fields
public Simulator()
{
grid = new int[100][100];
inhabGrid = new boolean[grid.length][grid.length];
gridSize = grid.length - 1;
dist = grid.length;
TerrainGenerator gen = new TerrainGenerator();
setSize(dist,dist);
seedGrid();
findInhabLocation();
printGridToConsole();
}
public void paint(Graphics g)
{
//panting the grid
}
public void seedGrid()
{
//seeding
}
public boolean generateTerrain(int x1,int y1, int x2, int y2)
{
//terrain generator
}
public boolean mouseUp(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public boolean keyEvents(Event evt, int x, int y)
{
seedGrid(); //Create a new map
findInhabLocation();
repaint();
printGridToConsole();
return true;
}
public void findInhabLocation()
{
//find best inhabitant location
}
public int locateWater(int x, int y)
{
//finding closest water
}
public int locateJungle(int x, int y)
{
//finding closest jungle
}
}
}
That works fine in its own class but when I create a class for example:
public class TerrainGenerator
{
Simulator sim = new Simulator();
}
I know this has something to do with the constructor and it's something silly I am doing, what would be the best way of splitting up this app into classes, for example terrain generator, inhabitants etc
For example I want to be able to call a method from the 'TerrainGenerator' class and call i.e. terrainGenerator.generateTerrain
Your TerrainGenerator creates a Simulator object and vice versa, hence you'll end up with infinitely many objects (but at some point the stack is full and a stack overflow exception is thrown instead...)
Instead of creating a new Simulator in your TerrainGenerator, you should pass a reference to your current Simulator (well, actually, that is not a great design either, but I'm not gonna confuse you with the problems of circular references).
Heuster answer is correct, furthermore, I think you could take look at MVC to help you organize your classes.
Depending which should be the parent, you can pass in the instantiated class to the other, ie;
private final TerrainGenerator gen; //if you need to save this.
public Simulator(TerrainGenerator terrainGenerator)
{
this.gen = terrainGenerator;
....etc
}
public class TerrainGenerator
{
Simulator sim = new Simulator(this);
}
or
private final TerrainGenerator gen; //if you need to save this.
public Simulator()
{
this.gen = new TerrainGenerator(this);
....etc
}
private final Simulator sim; //If you need to save it.
public class TerrainGenerator
{
public TerrainGenerator(Simulator simulator) {
this.sim = simulator;
}
}

Retrieve object from Java Vector by using its class name

I will start by explaining the scenario.
I have to create a Vector to hold a list of Circles.
Then I create a circle object, and add it to the Vector.
Finally I have to print the state of each circle in the list (the state isn't important to define, just it's colour and position etc).
Basically my problem is, how do I hold the circles so that I can then pass in the name of one of them and it will print the correct circle's state. It may be clearer to show you my code.
I have 3 classes, that main one called Lab83Test, the Vector one, called CircleList, and the Circle one, called Circle. (The formatting has gone weird and I can't fix it, so apologies!)
Lab83Test:
public class Lab83Test {
public static void main(String[] args) {
makeNewCircle();
}
public static void makeNewCircle() {
CircleList newList = new CircleList();
Circle newCircle = new Circle();
newList.addCircle(newCircle);
newCircle.makeVisible();
newList.printDetails();
}
}
CircleList:
import java.util.Vector;
public class CircleList {
private Vector circleVector;
public CircleList() {
circleVector = new Vector();
}
public void addCircle(Circle circleName) {
circleVector.add(circleName);
printDetails();
}
public void addCircleToPlace(Circle circleName, int pos) {
circleVector.add(pos, circleName);
printDetails();
}
public void removeCircleFromPos(int pos) {
circleVector.remove(pos);
printDetails();
}
public void removeAllCircles(int pos) {
circleVector.clear();
printDetails();
}
public void printDetails() {
}
}
The circle class isn't too important, and it has a lot of methods for moving the circle and stuff. The main thing is that it has to return its state.
If you just want to iterate over all Circel in your list and print their name, you can do it this way:
public void printDetails() {
for (Circle c: circleVector) {
System.out.println(String.format("%s: center=(%.1f/%.1f) radius=%.1f", c.getName(), c.getCenterX(), c.getCenterY(), c.getRadius()));
}
}
I don't know how your Circle class looks so I just assumed some method names.
If you want to find a specific circle by name:
for (Circle c: circleVector) {
if (c.getName().equals(nameToFind)) return c;
}
Or you could use a Map<String, Circle> instead of your vector and just do return circleMap.get(name);. Your addCircle() would then look like this:
public void addCircle(Circle circle) {
circleMap.add(circle.getName(), circle);
printDetails();
}
Edit1: regarding your comment: Your vector does not have a defined type. Change this:
...
public class CircleList {
private Vector<Circle> circleVector;
public CircleList() {
circleVector = new Vector<Circle>();
}
...

Categories