Hi!
Sorry to bother you again with this but I need to use undirected graphs that might contain cycles in order to put my implementation of the cells-and-portals algorithm into JME 2.0. I tried with SwitchNode but I need to activate several nodes at a time, I tried to convert my graphs into trees, it should work but it will be less efficient because you have to visit the whole tree for several tasks because of the removal of cycles (to avoid forgetting nodes that would be linked in the graph) especially when you're looking for all visible nodes in an indoor environment. Implementing this is a huge task because it is required to write an equivalent of the package com.jme.scene, especially the classes Node and Spatial. Then, it would be fine for me to adapt my tiny implementation in order to receive a TriMesh and to output a forest of graphs with cells and portals, First Person Shooters would particularly benefit of it. Can someone tell me if it is really useful not only for me? Do I take the good road? Should I implement it in another way?
Tom suggested to use the class SwitchNode. I want to add all nodes (using SwitchNode) of a single graph into the list of children of a single node. The root node of such a graph contains some structural information (the links between each node). Then, before rendering, the forest of graphs is analysed, visible nodes are on, invisible are off (see the documentation of the class SwitchNode). I hope it might help some people.
Maybe the schema below might help you to understand what I mean:
You know, I am still having an issue trying to understand exactly what you are asking for; if its for advice I would say get a proof of concept up that isn't too complex, to see what you can do w/ jME. If the proof of concept is a success look at how to make a general case that could be worked into jME (with a minimum of changes to the already existing code ;)).
basixs said:
You know, I am still having an issue trying to understand exactly what you are asking for; if its for advice I would say get a proof of concept up that isn't too complex, to see what you can do w/ jME. If the proof of concept is a success look at how to make a general case that could be worked into jME (with a minimum of changes to the already existing code ;)).
TUER is already based on forests of graphs, it is already a proof of concept that has worked quite reliably for months :D
On the other hand, I think about another kind of problem. I already submitted a few tiny fixes for the JOGL renderer, it wasn't a very original source code... but I refuse to put into BSD license the implementation of algorithms on which I have put several years of work, it will be under GPL license (for political reasons) like the whole source code of TUER and I think my mechanism could be engine-agnostic, it could work with Xith3D (it would require a bigger effort), Java3D (almost as easily as in JME except for the notion of switches inside nodes) and Ardor3D. As far as I know, I assume JME 2.0 needs no change to support it. If it is possible to put an implementation that fits into JME 2.0 but with a different license, I will be very happy to contribute, otherwise people will be free to download my extension separately.
Ah. you mean this?
http://www.youtube.com/watch?v=pk8mgTDAsio
So, in very simple terms ;); what are you asking?
(or is this just a probe for comments?)
Would just setting the cull hint be a more simple way of implementing a seperate culling system?
It seems like JME switchnodes are geared to changing the geometry that gets rendered rather than just setting whether you draw it or now.
I have not implemented such a thing so I don't know how either performs.
Alric said:
Would just setting the cull hint be a more simple way of implementing a seperate culling system?
It seems like JME switchnodes are geared to changing the geometry that gets rendered rather than just setting whether you draw it or now.
I have not implemented such a thing so I don't know how either performs.
I don't know how to implement it by using the cull hint. However, the support of undirected non-acyclical graphs should be used for other purposes, not only as a culling system even though it is one of the main interest. In the worst case, maybe I can create a class that looks like SwitchNode but that does only what I want as you say switch nodes are gearing to do a lot more. What do you think about it?
Edit.: I have watched the source code of SwitchNode, it is quite simple but maybe I should rather use a cull hint on each node. I'm quite a newbie with JME so your suggestions are welcome :D
I might have caused a bit of confusion about the SwitchNode. When I mentioned it on javagaming.org I was referring to the BitSwitchNode in the Quake3 benchmark source. Full code can be found here:
http://home.halden.net/tombr/jmeq3.jar
Here is the implementation:
import com.jme.renderer.Renderer;
import com.jme.scene.*;
import java.util.BitSet;
/**
* <code>BSwitchNode</code> defines a node that maintains a set of active children
*/
public class BitSwitchNode extends Node {
private static final long serialVersionUID = 1L;
protected boolean bitSet[];
/**
* Constructor instantiates a new <code>BitSwitchNode</code> object. The name
* of the node is provided during construction.
*
* @param name the name of the node.
* @param bitSet contains which children to render. Length must match number of children.
*/
public BitSwitchNode(String name, boolean bitSet[]) {
super(name);
this.bitSet = bitSet;
}
/**
* Draws the children that is enabled by the bitset.
* This function should be called internally only.
*
* @param r
* The render system to draw the child.
*/
public void draw(Renderer r) {
int renderedCnt = 0;
for (int i=0; i<bitSet.length; i++) {
if (bitSet[i]) {
getChild(i).onDraw(r);
renderedCnt++;
}
}
}
}
By changing the values in the boolean array passed i the constructor you control which children to render. This is all JME coded needed to implement a room/portal algorithm. Or any other custom culling algorithm for that matter. The room/portal code can be a separate API that is independent of rendering.
Thanks tom. Therefore, I could use a BitSwitchNode per graph or doing the same thing with conventional nodes but by modifying cull hints.
I'm currently very busy but I have succeeded in going on implementing the cells-and-portals algorithm inside JME.
For the moment, I can load the cells and the portals as JBIN models, put them into separate lists (one list per network/graph) with an identifier (NID<nid>CID<cid> for the cells, NID<nid>CID<cid>CID<cid> for the portals), create a node per network, add all cells of a single network into this newly created node (create a node per cell as an instance of the class Cell that will be able to contain a list of instances of the class Portal ), create a node per portal, find its linked cells, put them into the portal and put this portal into its both linked cells.
Just before rendering, the cull hint of all nodes is set at "always", then we look for the network and the cell containing the player, the cull hint of this cell is set at "never" and the Breadth First Search is used to visit this graph/network, the cull hint of all its visible cells is set at "never", a cell is considered as visible if it is linked to another visible cell and the portal that links them is visible (in the view frustum).
The source code is not completely finished but you can watch it
The source code is not completely finished but you can watch it
Do you mean there is a video posted??
basixs said:
The source code is not completely finished but you can watch it
Do you mean there is a video posted??
Lol, I was tired when I wrote this. I meant "you can look at it". However, I remind you that the cells-and-portals algorithm is already integrated in my previous engine, you can already watch videos showing it in action. There is not yet any video showing the next implementation of this algorithm inside JME.
The schema below shows how I have finally structured my abstract data type, it has a bit changed:
Currently, I have to implement the effective culling.
The first try of culling with this allowed me to get 40 FPS instead of 12 FPS. The benefit of such algorithms is significant only on a very complex geometry.
The breadth first search is ready, it has improved a very little bit the speed (~41 FPS). Now, I have to look for all visible nodes, I start the search from the cell containing the player; if the portal of a cell is in the view frustum, I consider this cell is visible and I watch its children. Some annoying bugs in JME 2.0 waste the final result, especially the rendering :x
The demo is ready, go there for more information:
http://www.jmonkeyengine.com/jmeforum/index.php?topic=10543.0
I prepared the plumbing to add a mechanism to restrict the frustum currently used for the view culling by using the portal. I hope to have something to show in some days or some weeks in the worst case. Stay tuned.
As my explanation might be not clear enough, please look at this article, it deals with some algorithms used in Fallout 3:
http://geck.bethsoft.com/index.php/Occlusion_Culling
I am implementing this one:
To further refine the ability to define spaces and occluders, the GECK introduces more sophisticated spatial organization with portals/roombounds. Portal spaces are enclosed spaces which have very few visibility connections (portals) to other spaces. The portals can connect to other portal spaces, or can connect to the open, unbounded world.
When the camera is within a portal space, the system firsts tests any portals against the view frustum. If a portal is visible, the contents of the space it connects to are accumulated based on an intersection of the view frustum with the portals projected volume - this new volume becoming the new view frustum. If the connected space is a portal space, this process can repeat as necessary.
Hi!
Please find below the source code of the method AbstractCamera.getScreenCoordinates(Vector3f, Vector3f).
/**
* Implementation contributed by Zbyl.
*
* @see Camera#getScreenCoordinates(Vector3f, Vector3f)
*/
public Vector3f getScreenCoordinates( Vector3f worldPosition, Vector3f store ) {
if ( store == null ) {
store = new Vector3f();
}
checkViewProjection();
tmp_quat.set( worldPosition.x, worldPosition.y, worldPosition.z, 1 );
modelViewProjection.mult( tmp_quat, tmp_quat );
tmp_quat.multLocal( 1.0f / tmp_quat.w );
store.x = ( ( tmp_quat.x + 1 ) * ( viewPortRight - viewPortLeft ) / 2 ) * getWidth();
store.y = ( ( tmp_quat.y + 1 ) * ( viewPortTop - viewPortBottom ) / 2 ) * getHeight();
store.z = ( tmp_quat.z + 1 ) / 2;
return store;
}
I need to do something different to be able to compare the projected coordinates with the frustum coordinates:
store.x = ( ( tmp_quat.x + 1 ) * ( viewPortRight - viewPortLeft ) / 2 );
store.y = ( ( tmp_quat.y + 1 ) * ( viewPortTop - viewPortBottom ) / 2 );
Then, I can compute the sub-frustums :D For example, if the leftmost abscissa of a portal is bigger than the left value of the current frustum, the left value of the new sub-frustum is equal with the leftmost abscissa of this portal.