Is there any easy way to show a selection box around an object?
Like maybe displaying the bounding box or simaliar?
A question to the code above:
TexCoords , why is this class missing (in my jme) :?
LightCombineMode.Off ;Mode.Strip,this.setVertexBuffer,this.setColorBuffer etc didn't work either
i have got the cvs jme2 version of cvs.dev.java.net
@problem above: i do it with find pick:
PickResults results = new BoundingPickResults();
results.setCheckDistance(true);
//scene: nodes where all the selectable things hang on
scene.findPick(ray,results);
if(results.getNumber() > 0) {
int i = 0;
float distance=results.getPickData(i).getDistance();
if(distance<110) {
//cast to my own node
CreatureModel creature= (CreatureModel) results.getPickData(i).getTargetMesh().getParentGeom().getParent().getParent().getParent();
//tell the node it is selected, there you can add bloom effect, lights, boxes, texts, etc.
creature.setSelected(true);
//change cursor
cursor=cursor0;cursorType=CursorType.FIGHT;}
}
You mean once you've clicked on a selectable object, like an enemy?
yes
I have no clue. When you find out, tell me. I'll be needing that rather soon!
Without attaching any geometry, you could use another renderpass to render the object in a way to indicate it is selected. I guess you could render the bounding box in the pass. I haven't done that exactly, but Scene Monitor uses a render pass to highlight items in the scene that have been selected. Its a place to start at least.
What would be awesome (but not compatible on low-end machines) is to bloom the selected object. Make it really intense, so it's glowing. That would be sweet…
Ahh… finally found TerrainMarker. It’s from MonkeyWorld3d
http://monkeyworld3d.cvs.sourceforge.net/checkout/monkeyworld3d/monkeyworld3d/src/com/mw3d/core/spatial/TerrainMarker.java?revision=1.2
Here is the code modified to work with jME2.0
EDIT: I don’t think its working…
EDIT: Okay it compiles now, but the highlighting is a little funky - need to fix it…
EDIT: Works now, just forgot to set it to a triangle strip
/*
* Copyright (c) 2005 MonkeyWorld3d - Monkey World 3d
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Monkey World 3d, MW3D, MonkeyWorld3d, nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import com.jme.math.FastMath;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.TexCoords;
import com.jme.scene.TriMesh;
import com.jme.util.geom.BufferUtils;
import com.jmex.terrain.TerrainPage;
/**
* This is a class which will be used to mark the terrain cursor position.
* I will try to create a circle with some radius.
*
* @author ndebruyn
* Created on May 31, 2005
*/
public class TerrainMarker extends TriMesh {
private static final long serialVersionUID = 1L;
private int radialSamples;
private float radius;
private float ringWidth;
private ColorRGBA colorRGBA;
private Vector3f[] vertex;
private Vector3f[] normal;
private ColorRGBA[] color;
private Vector2f[][] texture;
private int[] indices;
public TerrainMarker(String name, int radialSamples, float radius, float ringWidth, ColorRGBA colorRGBA) {
super(name);
this.radialSamples = radialSamples;
this.radius = radius;
this.ringWidth = ringWidth;
this.colorRGBA = colorRGBA;
texture = new Vector2f[1][];
// allocate vertices
int quantity = ((radialSamples+1) * 2);
vertex = new Vector3f[quantity];
normal = new Vector3f[quantity];
color = new ColorRGBA[quantity];
texture[0] = new Vector2f[quantity];
int indexQuantity = radialSamples * (6);
indices = new int[indexQuantity];
setGeometryData();
setColorData();
setIndexData();
this.setLightCombineMode(LightCombineMode.Off);
this.setTextureCombineMode(TextureCombineMode.Off);
this.setMode(Mode.Strip);
}
private void setGeometryData() {
// generate geometry
float f1 = 1.0F / (float)radialSamples;
int c = 0;
for (int r=0; r<radialSamples+1; r++) {
float f2 = FastMath.TWO_PI * (f1 * (float)r);
if (r == radialSamples) {
f2 = FastMath.TWO_PI * (f1 * (float)0);
}
//Outsize
float x = radius * FastMath.cos(f2);
float z = radius * FastMath.sin(f2);
float y = 0.0F;
Vector3f vector3f2out = new Vector3f(x, y, z);
//Insize
x = (radius-(ringWidth)) * FastMath.cos(f2);
z = (radius-(ringWidth)) * FastMath.sin(f2);
y = 0.0F;
Vector3f vector3f2in = new Vector3f(x, y, z);
vertex[c] = vector3f2out;
c++;
vertex[c] = vector3f2in;
c++;
}
this.setVertexBuffer(BufferUtils.createFloatBuffer(vertex));
this.setColorBuffer(BufferUtils.createFloatBuffer(color));
this.setVertexBuffer(BufferUtils.createFloatBuffer(normal));
this.setTextureCoords(new TexCoords(BufferUtils.createFloatBuffer(texture[0]), 0));
}
private void setIndexData() {
// generate connectivity
int c = 0;
int t = 0;
for (; t < indices.length; t=t+3) {
indices[t] = c;
indices[t+1] = c+1;
indices[t+2] = c+2;
c++;
}
this.setIndexBuffer(BufferUtils.createIntBuffer(indices));
}
private void setColorData() {
for (int x = 0; x < color.length; x++) {
color[x] = colorRGBA;
}
this.setColorBuffer(BufferUtils.createFloatBuffer(color));
}
/**
* We need to update the marker position.
*/
public void update(Vector3f midPoint, TerrainPage page) {
setLocalTranslation(midPoint);
float x = getLocalTranslation().x;
float y = getLocalTranslation().y;
float z = getLocalTranslation().z;
float newY;
float incrMent = 0.3F;
float oldY = 0.0F;
for (int t=0; t<vertex.length; t++) {
newY = page.getHeight(x+vertex[t].x, z+vertex[t].z);
//I the value is a NaN set it to be 0.0F
if (Float.isNaN(newY) || newY > radius+y) {
vertex[t].y = (oldY-y) + incrMent;
} else {
vertex[t].y = (newY-y) + incrMent;
oldY = newY;
}
}
reconstruct(vertex, normal, color, texture[0]);
updateGeometricState(0.0F, true);
}
private void reconstruct(Vector3f[] vertex2, Vector3f[] normal2,
ColorRGBA[] color2, Vector2f[] vector2fs) {
// TODO Auto-generated method stub
super.reconstruct(BufferUtils.createFloatBuffer(vertex),
BufferUtils.createFloatBuffer(normal),
BufferUtils.createFloatBuffer(color),
new TexCoords(BufferUtils.createFloatBuffer(texture[0]), 0));
}
public void reset(ColorRGBA colorRGBA, float radius) {
if (colorRGBA != null)
this.colorRGBA = colorRGBA;
this.radius = radius;
setGeometryData();
setColorData();
reconstruct(vertex, normal, color, texture[0]);
updateGeometricState(0.0F, true);
}
public float getRadius() {
return radius;
}
}
and a test:
import java.util.HashMap;
import javax.swing.ImageIcon;
import jmetest.input.TestThirdPersonController;
import jmetest.terrain.TestTerrain;
import com.jme.app.SimpleGame;
import com.jme.app.AbstractGame.ConfigShowMode;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.ChaseCamera;
import com.jme.input.ThirdPersonHandler;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.FaultFractalHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
public class TerrainMarkerTest extends SimpleGame{
private Node m_character;
private ChaseCamera chaser;
private TerrainPage page;
private TerrainMarker characterMarker;
public static void main(String[] args) {
TerrainMarkerTest app = new TerrainMarkerTest();
app.setConfigShowMode(ConfigShowMode.AlwaysShow);
app.start();
}
@Override
protected void simpleInitGame() {
// TODO Auto-generated method stub
setupCharacter();
setupTerrain();
setupChaseCamera();
setupInput();
characterMarker = new TerrainMarker("charMarker", 5,
10f,//((BoundingBox)m_character.getWorldBound()).xExtent,
2f, ColorRGBA.green);
rootNode.attachChild(characterMarker);
//setupJoystick();
}
protected void simpleUpdate() {
chaser.update(tpf);
float camMinHeight = page.getHeight(cam.getLocation()) + 2f;
if (!Float.isInfinite(camMinHeight) && !Float.isNaN(camMinHeight)
&& cam.getLocation().y <= camMinHeight) {
cam.getLocation().y = camMinHeight;
cam.update();
}
float characterMinHeight = page.getHeight(m_character
.getLocalTranslation())+((BoundingBox)m_character.getWorldBound()).yExtent;
if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) {
m_character.getLocalTranslation().y = characterMinHeight;
}
characterMarker.update(m_character.getWorldTranslation(), page);
}
private void setupCharacter() {
Box b = new Box("box", new Vector3f(), 5,5,5);
b.setModelBound(new BoundingBox());
b.updateModelBound();
m_character = new Node("char node");
rootNode.attachChild(m_character);
m_character.attachChild(b);
m_character.updateWorldBound(); // We do this to allow the camera setup access to the world bound in our setup code.
TextureState ts = display.getRenderer().createTextureState();
ts.setEnabled(true);
ts.setTexture(
TextureManager.loadTexture(
TestThirdPersonController.class.getClassLoader().getResource(
"jmetest/data/images/Monkey.jpg"),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear));
m_character.setRenderState(ts);
}
private void setupTerrain() {
rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
display.getRenderer().setBackgroundColor(
new ColorRGBA(0.5f, 0.5f, 0.5f, 1));
DirectionalLight dr = new DirectionalLight();
dr.setEnabled(true);
dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
dr.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
dr.setDirection(new Vector3f(0.5f, -0.5f, 0));
CullState cs = display.getRenderer().createCullState();
cs.setCullFace(CullState.Face.Back);
cs.setEnabled(true);
rootNode.setRenderState(cs);
lightState.detachAll();
lightState.attach(dr);
FaultFractalHeightMap heightMap = new FaultFractalHeightMap(257, 32, 0,
255, 0.75f);
Vector3f terrainScale = new Vector3f(10, 1, 10);
heightMap.setHeightScale(0.001f);
page = new TerrainPage("Terrain", 33, heightMap.getSize(),
terrainScale, heightMap.getHeightMap(), false);
page.setDetailTexture(1, 16);
rootNode.attachChild(page);
ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
heightMap);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/grassb.png")), -128, 0, 128);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/highest.jpg")), 128, 255,
384);
pt.createTexture(512);
TextureState ts = display.getRenderer().createTextureState();
ts.setEnabled(true);
Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true);
ts.setTexture(t1, 0);
Texture t2 = TextureManager.loadTexture(TestThirdPersonController.class
.getClassLoader()
.getResource("jmetest/data/texture/Detail.jpg"),
Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear);
ts.setTexture(t2, 1);
t2.setWrap(Texture.WrapMode.Repeat);
t1.setApply(Texture.ApplyMode.Combine);
t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate);
t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor);
t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);
t2.setApply(Texture.ApplyMode.Combine);
t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned);
t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
t2.setCombineSrc1RGB(Texture.CombinerSource.Previous);
t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);
rootNode.setRenderState(ts);
FogState fs = display.getRenderer().createFogState();
fs.setDensity(0.5f);
fs.setEnabled(true);
fs.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f));
fs.setEnd(1000);
fs.setStart(500);
fs.setDensityFunction(FogState.DensityFunction.Linear);
fs.setQuality(FogState.Quality.PerVertex);
rootNode.setRenderState(fs);
}
private void setupChaseCamera() {
Vector3f targetOffset = new Vector3f();
targetOffset.y = ((BoundingBox) m_character.getWorldBound()).yExtent * 1.5f;
chaser = new ChaseCamera(cam, m_character);
chaser.setTargetOffset(targetOffset);
}
private void setupInput() {
HashMap<String, Object> handlerProps = new HashMap<String, Object>();
handlerProps.put(ThirdPersonHandler.PROP_DOGRADUAL, "true");
handlerProps.put(ThirdPersonHandler.PROP_TURNSPEED, ""+(1.0f * FastMath.PI));
handlerProps.put(ThirdPersonHandler.PROP_LOCKBACKWARDS, "false");
handlerProps.put(ThirdPersonHandler.PROP_CAMERAALIGNEDMOVE, "true");
input = new ThirdPersonHandler(m_character, cam, handlerProps);
input.setActionSpeed(100f);
}
}
TerrainMaker has highlighting or…?
I know a very used way today is by having a shader do a line draw around a selected object - if you get your hand on Rendermonkey the code seems pretty straight forward : ) Look under Non-photorealistic renders… and let us know how it goes hehe
EDIT: Found this in a different subject, where MrCoder mentions the shader in question (sorta) and there is a link at the top of the page http://www.jmonkeyengine.com/jmeforum/index.php?topic=8446.15
As far as i know jme2 is not on cvs.dev.java.net but on googlecode svn http://jmonkeyengine.googlecode.com/svn/trunk/ that would explain why you are missing some classes.
Hellmaster
now i got the svn version , I was years behind all the time XD and I didnt noticed it (damn jme wiki!)
New Problems followed:
anyone know why I can’t resolve javax.media? Do i have to use Eclipse RCP ? [solved]
and why does jme physics2 doesnt work with that jme version XD
“no lwjgl in java.library.path” (I added all libs and all of the lwjgl dir), I could cry :’(
(and I did:…Expand lwjgl.jar → Native Library Location → Edit → Workspace
The native libs are not directly in the "/lib" folder like the old messy 1.0. They are under separate folder underneath lib. For example, my mac has lwjgl's native lib set to: jme_SVN/lib/lwjgl/native/macosx (jme_SVN is just what I called my eclipse project.)
oh thxs , dummy me
There is also a new physics version for jme2 which can be checked out at http://jmephysics.googlecode.com/svn/trunk
Hellmaster
thank you, now I am finally on the newest standards (hopefully