first
@@ -1,118 +0,0 @@
|
||||
package org.example;
|
||||
|
||||
import org.ngengine.AsyncAssetManager;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.AsyncAssetLoadingFragment;
|
||||
import org.ngengine.components.fragments.InputHandlerFragment;
|
||||
import org.ngengine.components.fragments.MainViewPortFragment;
|
||||
import org.ngengine.gui.components.NLabel;
|
||||
import org.ngengine.gui.components.containers.NRow;
|
||||
import org.ngengine.gui.win.NWindowManagerComponent;
|
||||
import org.ngengine.gui.win.std.NHud;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.environment.EnvironmentProbeControl;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.Materials;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.FilterPostProcessor;
|
||||
import com.jme3.post.filters.ToneMapFilter;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.shape.Box;
|
||||
import com.jme3.util.SkyFactory;
|
||||
import com.jme3.util.SkyFactory.EnvMapType;
|
||||
|
||||
public class MainComponent implements Component<Object>, AsyncAssetLoadingFragment, MainViewPortFragment, InputHandlerFragment{
|
||||
// In a real-world application, you should probably split this into multiple components
|
||||
|
||||
private Spatial sky;
|
||||
private EnvironmentProbeControl evp;
|
||||
private Node rootNode;
|
||||
private Node characterNode;
|
||||
|
||||
@Override
|
||||
public void loadAssetsAsync(AsyncAssetManager assetManager) {
|
||||
// load resources
|
||||
sky = SkyFactory.createSky(assetManager, "Sky/citrus_orchard_puresky_4k.hdr", EnvMapType.EquirectMap);
|
||||
evp = new EnvironmentProbeControl(assetManager, 256);
|
||||
|
||||
// Tag sky for environment baking
|
||||
EnvironmentProbeControl.tagGlobal(sky);
|
||||
|
||||
// load character model
|
||||
characterNode = new Node("CharacterNode");
|
||||
Geometry characterGeom = new Geometry("MyCharacter", new Box(1f,1f,1f));
|
||||
characterNode.attachChild(characterGeom);
|
||||
|
||||
// set up material for character
|
||||
Material characterMat = new Material(assetManager, Materials.PBR);
|
||||
characterMat.setColor("BaseColor", ColorRGBA.White);
|
||||
characterMat.setFloat("Metallic", 1.0f);
|
||||
characterMat.setFloat("Roughness", 0.0f);
|
||||
characterGeom.setMaterial(characterMat);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receiveMainViewPort(ViewPort viewPort) {
|
||||
rootNode = getRootNode(viewPort);
|
||||
viewPort.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMainViewPortFilterPostprocessor(AssetManager assetManager, FilterPostProcessor fpp) {
|
||||
ToneMapFilter toneMapFilter = new ToneMapFilter(Vector3f.UNIT_XYZ.mult(1.6f));
|
||||
fpp.addFilter(toneMapFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime, Object arg) {
|
||||
// Compose the scene
|
||||
rootNode.attachChild(sky);
|
||||
rootNode.addControl(evp);
|
||||
rootNode.attachChild(characterNode);
|
||||
|
||||
NWindowManagerComponent windowManager = mng.getComponent(NWindowManagerComponent.class);
|
||||
windowManager.showWindow(NHud.class, (win,err)->{
|
||||
if(err != null) {
|
||||
System.err.println("Error showing HUD window: " + err.getMessage());
|
||||
return;
|
||||
}
|
||||
NRow topRow = win.getTop();
|
||||
NLabel label = new NLabel("Use WASD to move the cube");
|
||||
topRow.addChild(label);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(KeyInputEvent evt) {
|
||||
if(evt.getKeyCode() == KeyInput.KEY_W){
|
||||
characterNode.move(0, 0, -0.1f); // Move character forward
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_S) {
|
||||
characterNode.move(0, 0, 0.1f); // Move character backward
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_A) {
|
||||
characterNode.move(-0.1f, 0, 0); // Move character left
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_D) {
|
||||
characterNode.move(0.1f, 0, 0); // Move character right
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This source file was generated by the Gradle 'init' task
|
||||
*/
|
||||
package org.example;
|
||||
|
||||
import org.ngengine.NGEApplication;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.gui.win.NWindowManagerComponent;
|
||||
import org.ngengine.player.PlayerManagerComponent;
|
||||
import com.jme3.system.AppSettings;
|
||||
|
||||
public class NGEAppMain {
|
||||
public static void main(String[] args) {
|
||||
AppSettings settings = new AppSettings(true);
|
||||
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
|
||||
settings.setWidth(1280);
|
||||
settings.setHeight(720);
|
||||
settings.setGammaCorrection(true);
|
||||
settings.setSamples(4);
|
||||
settings.setStencilBits(8);
|
||||
settings.setDepthBits(24);
|
||||
settings.setVSync(true);
|
||||
settings.setGraphicsDebug(false);
|
||||
settings.setTitle("Nostr Game Engine Demo");
|
||||
|
||||
|
||||
Runnable appBuilder = NGEApplication.createApp(
|
||||
settings,
|
||||
app -> {
|
||||
ComponentManager mng = app.getComponentManager();
|
||||
mng.addAndEnableComponent(new PlayerManagerComponent());
|
||||
mng.addAndEnableComponent(new NWindowManagerComponent());
|
||||
|
||||
// Add more components as needed
|
||||
// ...
|
||||
|
||||
mng.addComponent(new MainComponent(), NWindowManagerComponent.class, PlayerManagerComponent.class);
|
||||
mng.enableComponent(MainComponent.class);
|
||||
}
|
||||
);
|
||||
appBuilder.run();
|
||||
}
|
||||
}
|
||||
55
app/src/main/java/org/ngengine/demo/adc/AdcDemo.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import org.ngengine.NGEApplication;
|
||||
import org.ngengine.ads.ImmersiveAdComponent;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.gui.win.NWindowManagerComponent;
|
||||
|
||||
import com.jme3.system.AppSettings;
|
||||
|
||||
public class AdcDemo {
|
||||
|
||||
|
||||
|
||||
public static void main(String arg[]){
|
||||
AppSettings settings = new AppSettings(true);
|
||||
settings.setRenderer(AppSettings.LWJGL_OPENGL32);
|
||||
settings.setWidth(1280);
|
||||
settings.setHeight(720);
|
||||
settings.setGammaCorrection(true);
|
||||
settings.setSamples(2);
|
||||
settings.setStencilBits(8);
|
||||
settings.setDepthBits(24);
|
||||
settings.setVSync(true);
|
||||
settings.setGraphicsDebug(false);
|
||||
settings.setX11PlatformPreferred(true);
|
||||
settings.setTitle("Nostr Game Engine Demo");
|
||||
|
||||
|
||||
|
||||
|
||||
Runnable appBuilder = NGEApplication.createApp(settings, app -> {
|
||||
ImmersiveAdComponent dep = app.enableAds();
|
||||
|
||||
|
||||
ComponentManager mng = app.getComponentManager();
|
||||
mng.addAndEnableComponent(new LoadingScreenComponent(), null, new Object[] { NWindowManagerComponent.class });
|
||||
|
||||
mng.addAndEnableComponent(new NWindowManagerComponent());
|
||||
mng.addAndEnableComponent(new PhysicsComponent());
|
||||
mng.addAndEnableComponent(new SoundComponent());
|
||||
mng.addAndEnableComponent(new PostprocessingComponent());
|
||||
mng.addAndEnableComponent(new MapComponent(), null, new Object[]{ PhysicsComponent.class, ImmersiveAdComponent.class});
|
||||
mng.addAndEnableComponent(new CharacterComponent(), null, new Object[] {
|
||||
MapComponent.class, PhysicsComponent.class });
|
||||
mng.addAndEnableComponent(new HudComponent(), null, new Object[] { CharacterComponent.class });
|
||||
|
||||
app.getJme3App().setFlyCamEnabled(true);
|
||||
app.getJme3App().getInputManager().setCursorVisible(false);
|
||||
|
||||
|
||||
});
|
||||
|
||||
appBuilder.run();
|
||||
}
|
||||
}
|
||||
156
app/src/main/java/org/ngengine/demo/adc/CharacterComponent.java
Normal file
@@ -0,0 +1,156 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import org.ngengine.ViewPortManager;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.InputHandlerFragment;
|
||||
import org.ngengine.components.fragments.LogicFragment;
|
||||
import org.ngengine.components.fragments.MainViewPortFragment;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.bullet.control.CharacterControl;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.jme3.input.event.MouseMotionEvent;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
|
||||
public class CharacterComponent implements Component<Object>, InputHandlerFragment, LogicFragment{
|
||||
private static final float MAX_PITCH = FastMath.HALF_PI - 0.1f;
|
||||
|
||||
private Node player;
|
||||
private CharacterControl characterControl;
|
||||
private boolean debugCam = false;
|
||||
private float currentYaw = 0;
|
||||
private float currentPitch = 0;
|
||||
private Vector3f walkDirection = new Vector3f();
|
||||
private boolean left = false;
|
||||
private boolean right = false;
|
||||
private boolean up = false;
|
||||
private boolean down = false;
|
||||
private boolean jump = false;
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
Node rootNode = vpm.getRootNode(mainViewPort);
|
||||
|
||||
player = new Node("Player");
|
||||
player.setLocalTranslation(new Vector3f(-33.665176f, 41.3f, -23.83905f));
|
||||
player.setLocalRotation(new Quaternion(-0.10938066f, -0.004970028f, -5.469133f, 0.9939874f));
|
||||
rootNode.attachChild(player);
|
||||
|
||||
PhysicsComponent physics = mng.getComponent(PhysicsComponent.class);
|
||||
characterControl = physics.createCharacterControl(player);
|
||||
physics.addAll(player);
|
||||
|
||||
System.out.println("Character ready");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
PhysicsComponent physics = mng.getComponent(PhysicsComponent.class);
|
||||
physics.removeAll(player);
|
||||
player.removeFromParent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(ComponentManager mng, KeyInputEvent evt) {
|
||||
if(evt.getKeyCode() == KeyInput.KEY_W) {
|
||||
up = evt.isPressed();
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_S) {
|
||||
down = evt.isPressed();
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_A) {
|
||||
left = evt.isPressed();
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_D) {
|
||||
right = evt.isPressed();
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_SPACE) {
|
||||
jump = evt.isPressed();
|
||||
} else if(evt.getKeyCode() == KeyInput.KEY_F){
|
||||
if(evt.isPressed()){
|
||||
debugCam = !debugCam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void updateAppLogic(ComponentManager mng, float tpf){
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
if(!debugCam){
|
||||
Camera cam = mainViewPort.getCamera();
|
||||
Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
|
||||
Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
|
||||
camDir.y = 0;
|
||||
camLeft.y = 0;
|
||||
walkDirection.set(0, 0, 0);
|
||||
if (left) {
|
||||
walkDirection.addLocal(camLeft);
|
||||
}
|
||||
if (right) {
|
||||
walkDirection.addLocal(camLeft.negate());
|
||||
}
|
||||
if (up) {
|
||||
walkDirection.addLocal(camDir);
|
||||
}
|
||||
if (down) {
|
||||
walkDirection.addLocal(camDir.negate());
|
||||
}
|
||||
if (jump){
|
||||
characterControl.jump();
|
||||
}
|
||||
characterControl.setWalkDirection(walkDirection);
|
||||
}
|
||||
|
||||
if (!debugCam) {
|
||||
mainViewPort.getCamera().setLocation(characterControl.getPhysicsLocation());
|
||||
mainViewPort.getCamera().getLocation().y -= 0.5f;
|
||||
mainViewPort.getCamera().lookAtDirection(characterControl.getViewDirection(), Vector3f.UNIT_Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isOnGround(){
|
||||
return characterControl.onGround();
|
||||
}
|
||||
|
||||
public boolean isWalking(){
|
||||
return walkDirection.lengthSquared() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseMotionEvent(ComponentManager mng, MouseMotionEvent evt) {
|
||||
float sensitivity = 0.0005f;
|
||||
|
||||
|
||||
// Update rotation angles
|
||||
currentYaw += -(float)evt.getDX() * sensitivity;
|
||||
currentPitch += -(float)evt.getDY() * sensitivity;
|
||||
|
||||
// Limit pitch to prevent flipping
|
||||
currentPitch = FastMath.clamp(currentPitch, -MAX_PITCH, MAX_PITCH);
|
||||
|
||||
// Create rotation quaternion from yaw angle (horizontal only)
|
||||
Quaternion rotation = new Quaternion();
|
||||
rotation.fromAngles(currentPitch, currentYaw, 0);
|
||||
|
||||
// Set character direction based on yaw only (horizontal movement)
|
||||
Vector3f viewDir = new Vector3f(0, 0, 1); // Forward vector
|
||||
viewDir = rotation.mult(viewDir);
|
||||
characterControl.setViewDirection(viewDir);
|
||||
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/org/ngengine/demo/adc/HudComponent.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.InputHandlerFragment;
|
||||
import org.ngengine.gui.components.NLabel;
|
||||
import org.ngengine.gui.win.NWindowManagerComponent;
|
||||
import org.ngengine.gui.win.std.NHud;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.simsilica.lemur.HAlignment;
|
||||
import com.simsilica.lemur.VAlignment;
|
||||
|
||||
public class HudComponent implements Component<Object>, InputHandlerFragment {
|
||||
private Runnable closeHud;
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
|
||||
mng.disableComponent(LoadingScreenComponent.class);
|
||||
NWindowManagerComponent windowManager = mng.getComponent(NWindowManagerComponent.class);
|
||||
|
||||
windowManager.showCursor(false);
|
||||
|
||||
this.closeHud= windowManager.showWindow(
|
||||
NHud.class,
|
||||
(win, err) -> {
|
||||
win.setFitContent(false);
|
||||
win.setFullscreen(true);
|
||||
NLabel crossair = new NLabel("+");
|
||||
crossair.setTextVAlignment(VAlignment.Center);
|
||||
crossair.setTextHAlignment(HAlignment.Center);
|
||||
win.getCenter().addChild(crossair);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
this.closeHud.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(ComponentManager mng, KeyInputEvent evt) {
|
||||
if(evt.getKeyCode() == KeyInput.KEY_E){
|
||||
if(evt.isPressed()){
|
||||
NWindowManagerComponent windowManager = mng.getComponent(NWindowManagerComponent.class);
|
||||
windowManager.toastAction(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.InputHandlerFragment;
|
||||
import org.ngengine.components.fragments.LogicFragment;
|
||||
import org.ngengine.gui.components.NLabel;
|
||||
import org.ngengine.gui.win.NWindowManagerComponent;
|
||||
import org.ngengine.gui.win.std.NHud;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.simsilica.lemur.HAlignment;
|
||||
import com.simsilica.lemur.VAlignment;
|
||||
|
||||
public class LoadingScreenComponent implements Component<Object>, LogicFragment {
|
||||
private Runnable closeHud;
|
||||
private NLabel txt;
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
|
||||
mng.disableComponent(LoadingScreenComponent.class);
|
||||
NWindowManagerComponent windowManager = mng.getComponent(NWindowManagerComponent.class);
|
||||
|
||||
windowManager.showCursor(false);
|
||||
|
||||
txt = new NLabel("Loading");
|
||||
|
||||
this.closeHud= windowManager.showWindow(
|
||||
NHud.class,
|
||||
(win, err) -> {
|
||||
win.setFitContent(false);
|
||||
win.setFullscreen(true);
|
||||
txt.setFontSize(32);
|
||||
txt.setTextVAlignment(VAlignment.Center);
|
||||
txt.setTextHAlignment(HAlignment.Center);
|
||||
win.getCenter().addChild(txt);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
this.closeHud.run();
|
||||
}
|
||||
|
||||
float time = 0;
|
||||
|
||||
@Override
|
||||
public void updateAppLogic(ComponentManager mng, float tpf) {
|
||||
time += tpf;
|
||||
if(txt!=null&&time>1f){
|
||||
time=0;
|
||||
txt.setText(txt.getText()+".");
|
||||
System.out.println(txt.getText());
|
||||
if(txt.getText().length()>15){
|
||||
txt.setText("Loading");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
134
app/src/main/java/org/ngengine/demo/adc/MapComponent.java
Normal file
@@ -0,0 +1,134 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.ngengine.AsyncAssetManager;
|
||||
import org.ngengine.ViewPortManager;
|
||||
import org.ngengine.ads.ImmersiveAdComponent;
|
||||
import org.ngengine.ads.ImmersiveAdControl;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.AsyncAssetLoadingFragment;
|
||||
import org.ngengine.components.fragments.MainViewPortFragment;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStore;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.asset.TextureKey;
|
||||
import com.jme3.bullet.collision.shapes.CollisionShape;
|
||||
import com.jme3.bullet.control.RigidBodyControl;
|
||||
import com.jme3.bullet.util.CollisionShapeFactory;
|
||||
import com.jme3.environment.EnvironmentProbeControl;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.Spatial.CullHint;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.util.SkyFactory;
|
||||
|
||||
public class MapComponent implements Component<Object>, AsyncAssetLoadingFragment {
|
||||
private Spatial map;
|
||||
private Spatial sky;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void loadAssetsAsync(ComponentManager mng, AsyncAssetManager assetManager, DataStore cache, Consumer<Object> preload) {
|
||||
try{
|
||||
// String cacheEntry = "adc/city000";
|
||||
// try{
|
||||
// if(cache.exists(cacheEntry)){
|
||||
// map = (Spatial)cache.read(cacheEntry);
|
||||
// }
|
||||
// } catch(Exception e){
|
||||
// }
|
||||
|
||||
if(map==null){
|
||||
System.out.println("AdCity: Loading map from assets...");
|
||||
map = assetManager.loadModel("adc/city/city.gltf");
|
||||
PhysicsComponent physics = mng.getComponent(PhysicsComponent.class);
|
||||
map.depthFirstTraversal(sx->{
|
||||
Object worldGuard = sx.getUserData("nge.worldguard");
|
||||
if(worldGuard!=null){
|
||||
sx.setCullHint(CullHint.Always);
|
||||
physics.createStaticRigidBody(sx);
|
||||
System.out.println("AdCity: Added worldguard collision to "+sx.getName());
|
||||
}
|
||||
});
|
||||
|
||||
// try {
|
||||
// cache.write(cacheEntry, map);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
} else {
|
||||
System.out.println("AdCity: Map loaded from cache.");
|
||||
}
|
||||
|
||||
TextureKey key = new TextureKey("adc/night-sky.png", true);
|
||||
key.setGenerateMips(false);
|
||||
Texture skyTextyre = assetManager.loadTexture(key);
|
||||
|
||||
sky = SkyFactory.createSky(assetManager, skyTextyre, SkyFactory.EnvMapType.EquirectMap);
|
||||
sky.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.PI, Vector3f.UNIT_Y));
|
||||
EnvironmentProbeControl.tagGlobal(sky);
|
||||
|
||||
preload.accept(map);
|
||||
preload.accept(sky);
|
||||
} catch(Exception e){
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
PhysicsComponent physics = mng.getComponent(PhysicsComponent.class);
|
||||
physics.addAll(map);
|
||||
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
AsyncAssetManager assetManager = mng.getGlobalInstance(AsyncAssetManager.class);
|
||||
|
||||
|
||||
Node rootNode = vpm.getRootNode(mainViewPort);
|
||||
rootNode.attachChild(map);
|
||||
rootNode.attachChild(sky);
|
||||
|
||||
int resolution = 128;
|
||||
rootNode.addControl(new EnvironmentProbeControl(assetManager, resolution));
|
||||
|
||||
ImmersiveAdControl adControl = map.getControl(ImmersiveAdControl.class);
|
||||
if(adControl==null){
|
||||
adControl = new ImmersiveAdControl(assetManager);
|
||||
map.addControl(adControl);
|
||||
mng.getComponent(ImmersiveAdComponent.class).register(adControl);
|
||||
}
|
||||
|
||||
System.out.println("Map ready");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
PhysicsComponent physics = mng.getComponent(PhysicsComponent.class);
|
||||
physics.removeAll(map);
|
||||
|
||||
ImmersiveAdControl adControl = map.getControl(ImmersiveAdControl.class);
|
||||
if(adControl!=null){
|
||||
mng.getComponent(ImmersiveAdComponent.class).unregister(adControl);
|
||||
}
|
||||
|
||||
map.removeFromParent();
|
||||
|
||||
sky.removeFromParent();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import org.ngengine.ViewPortManager;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.AppFragment;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.state.AppStateManager;
|
||||
import com.jme3.bullet.BulletAppState;
|
||||
import com.jme3.bullet.BulletAppState.ThreadingType;
|
||||
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
|
||||
import com.jme3.bullet.collision.shapes.CollisionShape;
|
||||
import com.jme3.bullet.control.CharacterControl;
|
||||
import com.jme3.bullet.control.RigidBodyControl;
|
||||
import com.jme3.bullet.util.CollisionShapeFactory;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
|
||||
public class PhysicsComponent implements Component<Object>{
|
||||
private BulletAppState physics;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
physics = new BulletAppState();
|
||||
physics.setThreadingType(ThreadingType.PARALLEL);
|
||||
AppStateManager stateManager=mng.getGlobalInstance(AppStateManager.class);
|
||||
stateManager.attach(physics);
|
||||
System.out.println("Physics ready");
|
||||
|
||||
}
|
||||
|
||||
public RigidBodyControl createStaticRigidBody(Spatial sx){
|
||||
CollisionShape shp = CollisionShapeFactory.createDynamicMeshShape(sx);
|
||||
RigidBodyControl rb = new RigidBodyControl(shp, 0);
|
||||
rb.setFriction(1f);
|
||||
sx.addControl(rb);
|
||||
return rb;
|
||||
}
|
||||
|
||||
public CharacterControl createCharacterControl(Node player){
|
||||
CharacterControl characterControl = new CharacterControl(new CapsuleCollisionShape(1.5f, 0.8f), .1f);
|
||||
player.addControl(characterControl);
|
||||
return characterControl;
|
||||
}
|
||||
|
||||
public void addAll(Spatial v){
|
||||
physics.getPhysicsSpace().addAll(v);
|
||||
}
|
||||
|
||||
public void removeAll(Spatial v){
|
||||
physics.getPhysicsSpace().removeAll(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
AppStateManager stateManager = mng.getGlobalInstance(AppStateManager.class);
|
||||
stateManager.detach(physics);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.swing.text.View;
|
||||
|
||||
import org.ngengine.ViewPortManager;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.AssetLoadingFragment;
|
||||
import org.ngengine.components.fragments.LogicFragment;
|
||||
import org.ngengine.components.fragments.MainViewPortFragment;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStore;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.post.FilterPostProcessor;
|
||||
import com.jme3.post.filters.BloomFilter;
|
||||
import com.jme3.post.filters.FXAAFilter;
|
||||
import com.jme3.post.filters.FogFilter;
|
||||
import com.jme3.post.filters.KHRToneMapFilter;
|
||||
import com.jme3.post.ssao.SSAOFilter;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.texture.Image.Format;
|
||||
|
||||
public class PostprocessingComponent implements Component<Object>, LogicFragment {
|
||||
private FilterPostProcessor fpp;
|
||||
|
||||
|
||||
|
||||
|
||||
FogFilter fog;
|
||||
SSAOFilter ssaoFilter;
|
||||
BloomFilter bloom;
|
||||
KHRToneMapFilter tonemap;
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
AssetManager assetManager = mng.getGlobalInstance(AssetManager.class);
|
||||
|
||||
fpp = new FilterPostProcessor(assetManager);
|
||||
fpp.setFrameBufferDepthFormat(Format.Depth24Stencil8);
|
||||
fpp.setNumSamples(2);
|
||||
mainViewPort.addProcessor(fpp);
|
||||
|
||||
ssaoFilter = new SSAOFilter(2.9299974f, 25f, 5.8100376f, 0.091000035f);
|
||||
ssaoFilter.setScale(0.6f);
|
||||
ssaoFilter.setBias(0.79f);
|
||||
ssaoFilter.setApproximateNormals(false);
|
||||
ssaoFilter.setSampleRadius(0.8f);
|
||||
ssaoFilter.setIntensity(63f);
|
||||
|
||||
fpp.addFilter(ssaoFilter);
|
||||
|
||||
fog = new FogFilter();
|
||||
fog.setFogDistance(211f);
|
||||
fog.setFogDensity(0.4f);
|
||||
fog.setFogColor(new ColorRGBA(15.0f / 255.0f, 0.0f, 110f / 255.0f, 1f));
|
||||
fpp.addFilter(fog);
|
||||
|
||||
|
||||
|
||||
tonemap = new KHRToneMapFilter();
|
||||
tonemap.setGamma(new Vector3f(0.9f,0.9f,0.9f));
|
||||
tonemap.setExposure(new Vector3f(0.7f,0.6f,0.8f));
|
||||
fpp.addFilter(tonemap);
|
||||
|
||||
bloom=new BloomFilter();
|
||||
bloom.setDownSamplingFactor(2);
|
||||
bloom.setBlurScale(1.17f);
|
||||
bloom.setExposurePower(3.30f);
|
||||
bloom.setExposureCutOff(0.2f);
|
||||
bloom.setBloomIntensity(2.45f);
|
||||
|
||||
fpp.addFilter(bloom);
|
||||
|
||||
bloom.setBlurScale(1.f);
|
||||
bloom.setDownSamplingFactor(2);
|
||||
fog.setFogDensity(0.8f);
|
||||
bloom.setBloomIntensity(0.12f);
|
||||
tonemap.setExposure(new Vector3f(1.4f, 1f, 1f));
|
||||
bloom.setBloomIntensity(0.52f);
|
||||
|
||||
FXAAFilter fxaa = new FXAAFilter();
|
||||
fpp.addFilter(fxaa);
|
||||
|
||||
fog.setFogDensity(0.8f);
|
||||
tonemap.setExposure(new Vector3f(1.1f, 1.1f, 1f));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
mainViewPort.removeProcessor(fpp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAppLogic(ComponentManager mng, float tpf) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
115
app/src/main/java/org/ngengine/demo/adc/SoundComponent.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package org.ngengine.demo.adc;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.ngengine.AsyncAssetManager;
|
||||
import org.ngengine.ViewPortManager;
|
||||
import org.ngengine.components.Component;
|
||||
import org.ngengine.components.ComponentManager;
|
||||
import org.ngengine.components.fragments.AsyncAssetLoadingFragment;
|
||||
import org.ngengine.components.fragments.InputHandlerFragment;
|
||||
import org.ngengine.components.fragments.LogicFragment;
|
||||
import org.ngengine.components.fragments.MainViewPortFragment;
|
||||
import org.ngengine.components.fragments.RenderFragment;
|
||||
import org.ngengine.runner.Runner;
|
||||
import org.ngengine.store.DataStore;
|
||||
import org.ngengine.store.DataStoreProvider;
|
||||
|
||||
import com.jme3.audio.AudioData;
|
||||
import com.jme3.audio.AudioKey;
|
||||
import com.jme3.audio.AudioNode;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.event.KeyInputEvent;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
|
||||
public class SoundComponent implements Component<Object>, LogicFragment, AsyncAssetLoadingFragment, InputHandlerFragment {
|
||||
|
||||
private AudioNode backgroundMusic;
|
||||
private AudioNode footstepSound;
|
||||
private AudioNode jumpSound;
|
||||
private float lastFootstepTime = 0f;
|
||||
|
||||
@Override
|
||||
public void loadAssetsAsync(ComponentManager mng, AsyncAssetManager assetManager, DataStore cache, Consumer<Object> preload) {
|
||||
|
||||
|
||||
AudioKey audioKey = new AudioKey("adc/e.q._city.ogg", false, false);
|
||||
AudioData audioData = assetManager.loadAudio(audioKey);
|
||||
backgroundMusic = new AudioNode(audioData, audioKey);
|
||||
backgroundMusic.setLooping(true);
|
||||
backgroundMusic.setPositional(false);
|
||||
backgroundMusic.setVolume(0.4f);
|
||||
|
||||
AudioKey footstepKey = new AudioKey("adc/footstep.ogg", false, false);
|
||||
AudioData footstepData = assetManager.loadAudio(footstepKey);
|
||||
footstepSound = new AudioNode(footstepData, footstepKey);
|
||||
footstepSound.setLooping(false);
|
||||
footstepSound.setPositional(false);
|
||||
footstepSound.setVolume(0.5f);
|
||||
|
||||
|
||||
AudioKey jumpKey = new AudioKey("adc/jump.ogg", false, false);
|
||||
AudioData jumpData = assetManager.loadAudio(jumpKey);
|
||||
jumpSound = new AudioNode(jumpData, jumpKey);
|
||||
jumpSound.setLooping(false);
|
||||
jumpSound.setPositional(false);
|
||||
jumpSound.setVolume(0.5f);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime,
|
||||
Object arg) {
|
||||
|
||||
ViewPortManager vpm = mng.getGlobalInstance(ViewPortManager.class);
|
||||
ViewPort mainViewPort = vpm.getMainSceneViewPort();
|
||||
Node rootNode = vpm.getRootNode(mainViewPort);
|
||||
rootNode.attachChild(backgroundMusic);
|
||||
backgroundMusic.play();
|
||||
|
||||
rootNode.attachChild(footstepSound);
|
||||
rootNode.attachChild(jumpSound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) {
|
||||
backgroundMusic.removeFromParent();
|
||||
backgroundMusic.stop();
|
||||
footstepSound.removeFromParent();
|
||||
jumpSound.removeFromParent();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(ComponentManager mng, KeyInputEvent evt) {
|
||||
CharacterComponent character = mng.getComponent(CharacterComponent.class);
|
||||
|
||||
if(character !=null && evt.getKeyCode() == KeyInput.KEY_SPACE && evt.isPressed() && character.isOnGround()){
|
||||
jumpSound.playInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void updateAppLogic(ComponentManager mng, float tpf){
|
||||
CharacterComponent character = mng.getComponent(CharacterComponent.class);
|
||||
|
||||
if (character != null && character.isWalking() && character.isOnGround()) {
|
||||
lastFootstepTime += tpf;
|
||||
if (lastFootstepTime > 0.3f) {
|
||||
footstepSound.setPitch(1f - FastMath.nextRandomFloat() * 0.1f);
|
||||
footstepSound.setVolume(0.3f - FastMath.nextRandomFloat() * 0.1f);
|
||||
footstepSound.playInstance();
|
||||
lastFootstepTime = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
BIN
app/src/main/resources/adc/city/KB3D_NEC_AirCon_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 344 KiB |
|
After Width: | Height: | Size: 476 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_AirCon_normal.jpg
Normal file
|
After Width: | Height: | Size: 522 KiB |
|
After Width: | Height: | Size: 652 KiB |
|
After Width: | Height: | Size: 478 KiB |
|
After Width: | Height: | Size: 309 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_BannerA_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 352 KiB |
|
After Width: | Height: | Size: 127 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_BannerA_normal.jpg
Normal file
|
After Width: | Height: | Size: 498 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 90 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_BlackCloth_normal.jpg
Normal file
|
After Width: | Height: | Size: 411 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Brass_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 294 KiB |
|
After Width: | Height: | Size: 432 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Brass_normal.jpg
Normal file
|
After Width: | Height: | Size: 286 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Cardboard_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 448 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Cardboard_normal.jpg
Normal file
|
After Width: | Height: | Size: 514 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_ConcreteA_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 208 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_ConcreteA_normal.jpg
Normal file
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 371 KiB |
|
After Width: | Height: | Size: 394 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_ConcreteB_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 777 KiB |
|
After Width: | Height: | Size: 581 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_ConcreteB_normal.jpg
Normal file
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 331 KiB |
|
After Width: | Height: | Size: 378 KiB |
|
After Width: | Height: | Size: 789 KiB |
|
After Width: | Height: | Size: 456 KiB |
|
After Width: | Height: | Size: 206 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_ConcreteWall_normal.jpg
Normal file
|
After Width: | Height: | Size: 403 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Concrete_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 639 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Concrete_normal.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 296 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_DarkPanels_normal.jpg
Normal file
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 7.6 MiB |
|
After Width: | Height: | Size: 449 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_DecalSheet_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 452 KiB |
|
After Width: | Height: | Size: 419 KiB |
|
After Width: | Height: | Size: 621 KiB |
|
After Width: | Height: | Size: 314 KiB |
|
After Width: | Height: | Size: 413 KiB |
|
After Width: | Height: | Size: 718 KiB |
|
After Width: | Height: | Size: 594 KiB |
|
After Width: | Height: | Size: 415 KiB |
|
After Width: | Height: | Size: 660 KiB |
|
After Width: | Height: | Size: 347 KiB |
|
After Width: | Height: | Size: 395 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 384 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 163 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_GlassBlack_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 163 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_GlassBottle_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 233 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_GlassLamps_normal.jpg
Normal file
|
After Width: | Height: | Size: 550 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 79 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_GlassTinted_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 714 KiB |
|
After Width: | Height: | Size: 1010 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LeavesBush_normal.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Letters_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 281 KiB |
|
After Width: | Height: | Size: 122 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_Letters_normal.jpg
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightBlue_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightBlue_emissive.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightBlue_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightRed_basecolor.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightRed_emissive.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightRed_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightWhite_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 65 KiB |
BIN
app/src/main/resources/adc/city/KB3D_NEC_LightYellow_normal.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |