/*******************************************************************************
* Copyright 2013 pyros2097
*
* 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 scene3d.demo;
import scene3d.Actor3d;
import scene3d.Camera3d;
import scene3d.Group3d;
import scene3d.Stage3d;
import scene3d.actions.Actions3d;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.InputListener;
public class Scene3dDemo implements ApplicationListener {
Stage3d stage3d;
Stage stage2d;
Skin skin;
ModelBuilder modelBuilder;
CameraInputController camController;
Model model, model2, model3;
Actor3d knight, actor2, actor3, floor, skydome;
Group3d group3d;
Label fpsLabel;
Label visibleLabel;
Label positionLabel;
Label rotationLabel;
Label positionCameraLabel;
Label rotationCameraLabel;
public static void main(String[] argc) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.audioDeviceBufferCount = 20;
cfg.title = "Stage3d Test";
cfg.useGL20 = false;
cfg.width = 852;
cfg.height = 480;
new LwjglApplication(new Scene3dDemo(), cfg);
}
boolean rightKey, leftKey, upKey, downKey, spaceKey;
@Override
public void create () {
//2d stuff
stage2d = new Stage();
skin = new Skin(Gdx.files.internal("skin/uiskin.json"));
fpsLabel = new Label("ff", skin);
fpsLabel.setPosition(Gdx.graphics.getWidth() - 260, Gdx.graphics.getHeight()-40);
visibleLabel = new Label("ff", skin);
visibleLabel.setPosition(Gdx.graphics.getWidth() - 260, Gdx.graphics.getHeight()- 60);
positionLabel = new Label("Position", skin);
positionLabel.setPosition(Gdx.graphics.getWidth() - 260, Gdx.graphics.getHeight()- 80);
rotationLabel = new Label("Rotation", skin);
rotationLabel.setPosition(Gdx.graphics.getWidth() - 260, Gdx.graphics.getHeight()- 100);
positionCameraLabel = new Label("Position", skin);
positionCameraLabel.setPosition(20, Gdx.graphics.getHeight()- 40);
rotationCameraLabel = new Label("Rotation", skin);
rotationCameraLabel.setPosition(20, Gdx.graphics.getHeight()- 60);
stage2d.addActor(fpsLabel);
stage2d.addActor(visibleLabel);
stage2d.addActor(positionLabel);
stage2d.addActor(rotationLabel);
stage2d.addActor(positionCameraLabel);
stage2d.addActor(rotationCameraLabel);
stage2d.addListener(new InputListener(){
@Override
public boolean keyUp(InputEvent event, int keycode) {
if (keycode == Keys.LEFT) leftKey = false;
if (keycode == Keys.RIGHT) rightKey = false;
if (keycode == Keys.UP) upKey = false;
if (keycode == Keys.DOWN) downKey = false;
if (keycode == Keys.SPACE) spaceKey = false;
return super.keyUp(event, keycode);
}
@Override
public boolean keyDown(InputEvent event, int keycode) {
if (keycode == Keys.LEFT) leftKey = true;
if (keycode == Keys.RIGHT) rightKey = true;
if (keycode == Keys.UP) upKey = true;
if (keycode == Keys.DOWN) downKey = true;
if (keycode == Keys.SPACE) spaceKey = true;
return super.keyDown(event, keycode);
}
});
//3dstuff
stage3d = new Stage3d();
modelBuilder = new ModelBuilder();
model = modelBuilder.createBox(5f, 5f, 5f, new Material("Color", ColorAttribute.createDiffuse(Color.WHITE)),
Usage.Position | Usage.Normal);
model2 = modelBuilder.createBox(2f, 2f, 2f, new Material("Color", ColorAttribute.createDiffuse(Color.WHITE)),
Usage.Position | Usage.Normal);
actor2 = new Actor3d(model2, 10f, 0f, 0f);
model3 = modelBuilder.createBox(2f, 2f, 2f, new Material("Color", ColorAttribute.createDiffuse(Color.ORANGE)),
Usage.Position | Usage.Normal);
actor3 = new Actor3d(model3, -10f, 0f, 0f);
actor2.setColor(Color.RED);
actor2.setName("actor2");
actor3.setName("actor3");
camController = new CameraInputController(stage3d.getCamera());
InputMultiplexer im = new InputMultiplexer();
im.addProcessor(stage2d);// 2d should get click events first
//im.addProcessor(stage3d);
im.addProcessor(camController);
Gdx.input.setInputProcessor(im);
stage3d.touchable = Touchable.enabled; // only then will it detect hit actor3d
ModelBuilder builder = new ModelBuilder();
builder.begin();
MeshPartBuilder part = builder.part("floor", GL20.GL_TRIANGLES, Usage.Position | Usage.TextureCoordinates | Usage.Normal,
new Material());
for (float x = -200f; x < 200f; x += 10f) {
for (float z = -200f; z < 200f; z += 10f) {
part.rect(x, 0, z + 10f, x + 10f, 0, z + 10f, x + 10f, 0, z, x, 0, z, 0, 1, 0);
}
}
floor = new Actor3d(builder.end());
AssetManager am = new AssetManager();
am.load("data/g3d/knight.g3db", Model.class);
am.load("data/g3d/skydome.g3db", Model.class);
am.load("data/g3d/concrete.png", Texture.class);
am.finishLoading();
knight = new Actor3d(am.get("data/g3d/knight.g3db", Model.class), 0f, 18f, 0f);
knight.getAnimation().inAction = true;
knight.getAnimation().animate("Walk", -1, 1f, null, 0.2f);
skydome = new Actor3d(am.get("data/g3d/skydome.g3db", Model.class));
floor.materials.get(0).set(TextureAttribute.createDiffuse(am.get("data/g3d/concrete.png",
Texture.class)));
stage3d.addActor3d(skydome);
stage3d.addActor3d(floor);
knight.setPitch(-90f);
knight.setYaw(-130f);
testActor3d();
//stage3d.addAction3d(Actions3d.rotateBy(0f, 90f, 0f, 2f));
//testGroup3d();
//testStage3d();
}
float angle, angle2;
@Override
public void render () {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
stage3d.act();
stage3d.draw();
stage2d.act();
stage2d.draw();
camController.update();
fpsLabel.setText("Fps: " + Gdx.graphics.getFramesPerSecond());
visibleLabel.setText("Visible: " + stage3d.getRoot().visibleCount);
positionLabel.setText("Knight X:" + knight.getX()+" Y:"+knight.getY()+" Z:"+knight.getZ());
rotationLabel.setText("Knight Yaw:" + knight.getYaw()+" Pitch:"+knight.getPitch()+" "
+ "Roll:"+knight.getRoll());
positionCameraLabel.setText("Camera X:" + stage3d.getCamera().position.x
+" Y:"+stage3d.getCamera().position.y+" Z:"+stage3d.getCamera().position.z);
rotationCameraLabel.setText("Camera Yaw:" + stage3d.getCamera().direction.x
+" Pitch:"+stage3d.getCamera().direction.y+" "+ "Roll:"+stage3d.getCamera().direction.z);
angle = MathUtils.cosDeg(knight.getYaw() - 90); //90 degrees is correction factor
angle2 = -MathUtils.sinDeg(knight.getYaw() - 90);
if (upKey) {
knight.addAction3d(Actions3d.moveBy(angle, 0f, angle2));
stage3d.getCamera().translate(angle, 0f, angle2);
}
else if (downKey) {
knight.addAction3d(Actions3d.moveBy(-angle, 0f, -angle2));
stage3d.getCamera().translate(-angle, 0f, -angle2);
}
else if (rightKey) {
knight.rotateYaw(-2f);
if(stage3d.getCamera().direction.z > -0.76f)
Camera3d.rotateBy(-2f, 0f, 0f, 0f);
//stage3d.getCamera().translate(angle, 0f, angle2); //get the angle calculations rite to make
// the camera truly follow knight
}
else if (leftKey) {
knight.rotateYaw(2f);
if(stage3d.getCamera().direction.z < -0.63f)
Camera3d.rotateBy(2f, 0f, 0f, 0f);
}
/* private float stateTime;
float angleDegrees;
stateTime+= delta;
angleDegrees = stateTime * 10.0f;
camera.position.set(200f * MathUtils.sinDeg(angleDegrees),
20, -200.0f * MathUtils.cosDeg(angleDegrees));
camera.rotate(Vector3.Y, angleDegrees/10f*delta);*/
}
@Override
public void resize(int width, int height) {
stage2d.setViewport(width, height);
stage3d.setViewport(width, height);
}
@Override
public void pause() {}
@Override
public void resume() {}
@Override
public void dispose () {
stage3d.dispose();
}
void testActor3d(){
stage3d.addActor3d(knight);
stage3d.getCamera().position.set(knight.getX()+ 13f, knight.getY() + 24f, knight.getZ() + 45f);
//stage3d.getCamera().lookAt(knight.getX(), knight.getY(), knight.getZ());
//Camera3d.rotateCameraBy(knight.getYaw(), 0f, 0f, 1f);
//Camera3d.followOffset(20f, 20f, -20f);
//Camera3d.followActor3d(knight, false);
//stage3d.moveBy(-50f, 0f, 0f, 2f);
//stage3d.addActor3d(actor2);
//actor1.addAction3d(Actions3d.rotateTo(60f, 5f));
//actor1.addAction3d(Actions3d.scaleBy(0.5f, 0.5f, 0.5f, 5f, Interpolation.linear));
// actor1.addAction3d(Actions3d.forever(Actions3d.sequence(Actions3d.moveBy(50f, 0f, 0f, 10f),
// Actions3d.moveBy(-50f, 0f, 0f, 10f))));
// actor1.addAction3d(Actions3d.sequence(
// Actions3d.moveBy(7f, 0f, 0f, 2f),
// Actions3d.scaleTo(0.5f, 0.5f, 0.5f, 5f),
// Actions3d.moveBy(-7f, 0f, 0f, 2f)));
//actor1.addAction3d(Actions3d.scaleTo(1.2f, 1.2f, 1.2f, 1f));
//actor2.addAction3d(Actions3d.scaleBy(0.3f, 0.3f, 0.3f, 5f));
//actor1.addAction3d(Actions3d.sequence(Actions3d.moveBy(7f, 0f, 0f, 2f), Actions3d.moveBy(-7f, 0f, 0f, 2f)));
//actor1.addAction3d(Actions3d.moveTo(7f, 0f, 0f, 3f));
// actor1.addAction3d(Actions3d.moveTo(-10f, 0f, 0f, 2f));
/*
* Since both actions are running at same time we get the difference in x
* ans : actor.getX() = -3.0000014
*/
/* if you see this the setRotation method called alone works but after this moveTo is called and the actor1
* rotation is reset to original .. this is the problem because of transformation matrix
* and the Sequence action problem is i think because i'm using the pools from gdx.utils.pools
*/
//actor1.setRotation(59);
//actor1.setPosition(5f, 0f, 0f);
// actor2.addAction3d(Actions3d.moveBy(-7f, 0f, 0f, 2f));
// r.setRotation(59);
//r.addAction3d(Actions.rotateTo(59, 1f));
//r.addAction3d(Actions.rotateBy(59, 1f));
}
void testGroup3d(){
group3d = new Group3d();
group3d.setPosition(0f, 0f, 0f);
group3d.setName("group1");
stage3d.addActor3d(group3d);
group3d.addActor3d(knight);
group3d.addActor3d(actor2);
group3d.addActor3d(actor3);
group3d.addAction3d(Actions3d.sequence(Actions3d.moveTo(0f, 5f, 0f, 2f),
Actions3d.moveTo(5f, 0f, 0f, 2f), Actions3d.scaleTo(0f, 5f, 0f, 2f)));
}
void testStage3d(){
stage3d.addActor3d(knight);
stage3d.addActor3d(actor2);
stage3d.addAction3d(Actions3d.moveTo(-7f, 0f, 0f, 3f));
}
}