Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored client more towards a service oriented architecture.

Implemented message handling service that delegates messages to other services.
Created Engine service for 3D engine related things, moved most code from ClipmapTerrainSpike to it for now.
Some initial Entity classes.
  • Loading branch information...
commit d4c62801d1f87f7aef6839c20a8998fc109acfbc 1 parent a1a1964
@zzorn authored
Showing with 522 additions and 389 deletions.
  1. +12 −7 build.sbt
  2. +14 −0 src/main/java/org/skycastle/client/ActionMethod.java
  3. +6 −2 src/main/scala/org/skycastle/client/ClientServices.scala
  4. +8 −2 src/main/scala/org/skycastle/client/ClientServicesImpl.scala
  5. +0 −218 src/main/scala/org/skycastle/client/TerrainSpike.scala
  6. +13 −0 src/main/scala/org/skycastle/client/engine/Engine.scala
  7. +68 −104 src/main/scala/org/skycastle/client/{ClipmapTerrainSpike.scala → engine/EngineImpl.scala}
  8. +31 −0 src/main/scala/org/skycastle/client/entity/Appearance.scala
  9. +25 −0 src/main/scala/org/skycastle/client/entity/Entity.scala
  10. +14 −0 src/main/scala/org/skycastle/client/entity/EntityService.scala
  11. +23 −0 src/main/scala/org/skycastle/client/entity/EntityServiceImpl.scala
  12. +10 −0 src/main/scala/org/skycastle/client/entity/Location.scala
  13. +26 −0 src/main/scala/org/skycastle/client/entity/PlaceholderAppearance.scala
  14. +0 −2  src/main/scala/org/skycastle/client/messaging/MessageHandler.scala
  15. +50 −8 src/main/scala/org/skycastle/client/messaging/MessageHandlerImpl.scala
  16. +14 −0 src/main/scala/org/skycastle/client/messaging/handlers/ActionHandler.scala
  17. +27 −0 src/main/scala/org/skycastle/client/messaging/handlers/MethodActionHandler.scala
  18. +0 −1  src/main/scala/org/skycastle/client/network/ClientNetworking.scala
  19. +3 −6 src/main/scala/org/skycastle/client/network/ClientNetworkingImpl.scala
  20. +1 −1  src/main/scala/org/skycastle/client/network/protocol/binary/BinaryProtocol.scala
  21. +0 −1  src/main/scala/org/skycastle/client/network/protocol/binary/BinarySerializer.scala
  22. +19 −0 src/main/scala/org/skycastle/client/region/Region.scala
  23. +37 −0 src/main/scala/org/skycastle/client/region/RegionImpl.scala
  24. +43 −13 src/main/scala/org/skycastle/client/region/RegionService.scala
  25. +66 −0 src/main/scala/org/skycastle/client/region/RegionServiceImpl.scala
  26. +0 −8 src/main/scala/org/skycastle/client/terrain/TerrainServiceImpl.scala
  27. +1 −3 src/main/scala/org/skycastle/client/terrain/view/FunctionalTerrainBlockSource.scala
  28. +2 −1  src/main/scala/org/skycastle/client/terrain/view/Ground.scala
  29. +2 −3 src/main/scala/org/skycastle/client/terrain/view/GroundLodStrategy.scala
  30. +1 −3 src/main/scala/org/skycastle/client/terrain/view/GroundTree.scala
  31. +2 −1  src/main/scala/org/skycastle/client/terrain/view/SimpleGroundLodStrategy.scala
  32. +3 −4 src/main/scala/org/skycastle/client/terrain/view/TerrainBlock.scala
  33. +1 −1  src/main/scala/org/skycastle/utils/Services.scala
View
19 build.sbt
@@ -34,15 +34,20 @@ libraryDependencies += "com.dyuproject.protostuff" % "protostuff-collectionschem
libraryDependencies += "org.yaml" % "snakeyaml" % "1.11-SNAPSHOT"
+libraryDependencies += "org.scalastuff" % "scalabeans" % "0.3"
+
+libraryDependencies += "com.thoughtworks.paranamer" % "paranamer" % "0.3"
+
// Akka for parallel signals and messaging
-libraryDependencies ++= Seq(
- "se.scalablesolutions.akka" % "akka-actor" % "1.1.3",
- "se.scalablesolutions.akka" % "akka-slf4j" % "1.1.3",
- "se.scalablesolutions.akka" % "akka-typed-actor" % "1.1.3",
- "se.scalablesolutions.akka" % "akka-amqp" % "1.1.3",
- "se.scalablesolutions.akka" % "akka-testkit" % "1.1.3"
-)
+//libraryDependencies ++= Seq(
+// "se.scalablesolutions.akka" % "akka-actor" % "1.1.3",
+// "se.scalablesolutions.akka" % "akka-slf4j" % "1.1.3",
+// "se.scalablesolutions.akka" % "akka-typed-actor" % "1.1.3",
+// "se.scalablesolutions.akka" % "akka-amqp" % "1.1.3",
+// "se.scalablesolutions.akka" % "akka-testkit" % "1.1.3"
+//)
+
// JMonkey Engine 3.0 for 3D gfx
libraryDependencies ++= Seq( // Core lib
View
14 src/main/java/org/skycastle/client/ActionMethod.java
@@ -0,0 +1,14 @@
+package org.skycastle.client;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a method handles some types of messages from the server.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface ActionMethod {
+}
View
8 src/main/scala/org/skycastle/client/ClientServices.scala
@@ -1,9 +1,11 @@
package org.skycastle.client
+import engine.Engine
+import entity.EntityService
import messaging.MessageHandler
import network.ClientNetworking
import org.skycastle.utils.Services
-import terrain.TerrainService
+import region.RegionService
/**
* The services that the client is composed of.
@@ -14,8 +16,10 @@ trait ClientServices extends Services {
def messageHandler: MessageHandler
- def terrain: TerrainService
+ def entityService: EntityService
+ def regionService: RegionService
+ def engine: Engine
}
View
10 src/main/scala/org/skycastle/client/ClientServicesImpl.scala
@@ -1,8 +1,10 @@
package org.skycastle.client
+import engine.EngineImpl
+import entity.EntityServiceImpl
import messaging.MessageHandlerImpl
import network.ClientNetworkingImpl
-import terrain.TerrainServiceImpl
+import region.RegionServiceImpl
/**
*
@@ -13,5 +15,9 @@ class ClientServicesImpl extends ClientServices {
val networking = addService(new ClientNetworkingImpl(messageHandler))
- val terrain = addService(new TerrainServiceImpl())
+ val entityService = addService(new EntityServiceImpl())
+
+ val regionService = addService(new RegionServiceImpl(this))
+
+ val engine = addService(new EngineImpl())
}
View
218 src/main/scala/org/skycastle/client/TerrainSpike.scala
@@ -1,218 +0,0 @@
-package org.skycastle.client
-
-import com.jme3.app.SimpleApplication
-import com.jme3.material.Material
-import com.jme3.renderer.Camera
-import com.jme3.terrain.heightmap.AbstractHeightMap
-import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator
-import com.jme3.terrain.heightmap.HillHeightMap
-import com.jme3.bullet.control.CharacterControl
-import com.jme3.terrain.noise.fractal.FractalSum
-import com.jme3.app.state.ScreenshotAppState
-import com.jme3.terrain.geomipmap.grid.FractalTileLoader
-import com.jme3.terrain.noise.modulator.NoiseModulator
-import com.jme3.terrain.noise.ShaderUtils
-import com.jme3.terrain.noise.basis.FilteredBasis
-
-import com.jme3.terrain.heightmap.ImageBasedHeightMap
-import com.jme3.texture.Texture
-import com.jme3.texture.Texture.WrapMode
-import java.util.ArrayList
-import java.util.List
-import com.jme3.water.WaterFilter
-import com.jme3.post.FilterPostProcessor
-import com.jme3.audio.AudioNode
-import com.jme3.system.AppSettings
-import com.jme3.util.SkyFactory
-import com.jme3.terrain.noise.filter._
-import com.jme3.terrain.geomipmap.{TerrainGrid, TerrainLodControl, TerrainQuad}
-import com.jme3.math.{Vector3f, ColorRGBA}
-import com.jme3.asset.AssetManager
-import com.jme3.scene.{Node, Spatial}
-
-
-/**
- *
- */
-object TerrainSpike extends SimpleApplication {
-
- private val grassScale = 64;
- private val dirtScale = 16;
- private val rockScale = 128;
-
- private val lightDir = new Vector3f(-4.9f, -1.3f, 5.9f) // same as light source
- private val initialWaterHeight = 0.8f // choose a value for your scene
-
- def main(args: Array[String]) {
- val settings: AppSettings = new AppSettings(true)
- settings.setFrameRate(60)
- settings.setVSync(true)
- setSettings(settings);
- start()
- }
-
- @Override
- def simpleInitApp() {
-
- flyCam.setMoveSpeed(40)
-
- // Allow screenshots
- this.stateManager.attach(new ScreenshotAppState());
-
- // Terrain
- val terrainMaterial = createTerrainMaterial(assetManager, grassScale, dirtScale, rockScale)
- val groundFunction = createGround
- val terrain = createTerrain(groundFunction, terrainMaterial)
- this.rootNode.attachChild(terrain);
-
- // Water
- viewPort.addProcessor(createWater(assetManager, rootNode, lightDir, initialWaterHeight));
-
- // Sound
- // Chops on ubuntu 11.10
- val waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", false);
- waves.setLooping(true);
- audioRenderer.playSource(waves);
-
- // Sky
- this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
- rootNode.attachChild(createSky(assetManager))
-
- // Start pos
- this.getCamera().setLocation(new Vector3f(0, 300, 0));
-
- }
-
- def createGround: FilteredBasis = {
- val base = new FractalSum();
- base.setRoughness(0.7f);
- base.setFrequency(1.0f);
- base.setAmplitude(1.0f);
- base.setLacunarity(2.12f);
- base.setOctaves(8);
- base.setScale(0.02125f);
-
-
- /* TODO: This seems to be impossible to compile in scala....
- new NoiseModulator() {
- def value(in: Array[Float]): Float = {
- ShaderUtils.clamp(in(0) * 0.5f + 0.5f, 0, 1);
- }
- });
- */
- base.addModulator(new ClampingNoiseModulator())
-
- val ground = new FilteredBasis(base);
-
- val perturb = new PerturbFilter();
- perturb.setMagnitude(0.119f);
-
- val therm = new OptimizedErode();
- therm.setRadius(5);
- therm.setTalus(0.011f);
-
- val smooth = new SmoothFilter();
- smooth.setRadius(1);
- smooth.setEffect(0.7f);
-
- val iterate = new IterativeFilter();
- iterate.addPreFilter(perturb);
- iterate.addPostFilter(smooth);
- iterate.setFilter(therm);
- iterate.setIterations(1);
-
- ground.addPreFilter(iterate);
- ground
- }
-
- def createTerrain(ground: FilteredBasis, material: Material): TerrainQuad = {
- val patchSize: Int = 32 + 1
- val maxVisibleSize: Int = 128 + 1
- val terrain = new TerrainGrid("terrain", patchSize, maxVisibleSize, new FractalTileLoader(ground, 256f));
-
- terrain.setMaterial(material);
- terrain.setLocalTranslation(0, -120f, 0);
- terrain.setLocalScale(10f, 1f, 10f);
-
- val control = new TerrainLodControl(terrain, this.getCamera);
- control.setLodCalculator(new DistanceLodCalculator(patchSize, 2.7f)); // patch size, and a multiplier
- terrain.addControl(control);
- terrain
- }
-
- def createTerrainMaterial(assetManager: AssetManager, grassScale: Float, dirtScale: Float, rockScale: Float): Material = {
- // TERRAIN TEXTURE material
- val mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
-
-
- // Parameters to material:
- // regionXColorMap: X = 1..4 the texture that should be applied to state X
- // regionX: a Vector3f containing the following information:
- // regionX.x: the start height of the region
- // regionX.y: the end height of the region
- // regionX.z: the texture scale for the region
- // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
- // slopeColorMap: the texture to be used for cliffs, and steep mountain sites
- // slopeTileFactor: the texture scale for slopes
- // terrainSize: the total size of the terrain (used for scaling the texture)
- // GRASS texture
- val grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg")
- grass.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("region1ColorMap", grass);
- mat_terrain.setVector3("region1", new Vector3f(15, 200, grassScale));
-
- // DIRT texture
- val dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
- dirt.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("region2ColorMap", dirt);
- mat_terrain.setVector3("region2", new Vector3f(0, 20, dirtScale));
-
- // ROCK texture
- val rock = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
- rock.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("region3ColorMap", rock);
- mat_terrain.setVector3("region3", new Vector3f(198, 260, rockScale));
-
- mat_terrain.setTexture("region4ColorMap", rock);
- mat_terrain.setVector3("region4", new Vector3f(198, 260, rockScale));
-
- mat_terrain.setTexture("slopeColorMap", rock);
- mat_terrain.setFloat("slopeTileFactor", 32);
-
- mat_terrain.setFloat("terrainSize", 513);
- mat_terrain
- }
-
- def createWater(assetManager: AssetManager, rootNode: Node, lightDir: Vector3f, initialWaterHeight: Float): FilterPostProcessor = {
- val water = new WaterFilter(rootNode, lightDir);
- water.setWaterHeight(initialWaterHeight);
- water.setSpeed(0.6f)
- water.setWaveScale(0.001f)
- water.setDeepWaterColor(new ColorRGBA(0.0001f, 0.00196f, 0.145f, 1.0f))
- water.setWaterColor(new ColorRGBA(0.1f, 0.11f, 0.145f, 1.0f))
- water.setWaterTransparency(0.2f)
- water.setUseFoam(false)
-
- val fpp = new FilterPostProcessor(assetManager);
- fpp.addFilter(water);
- fpp
- }
-
- override def simpleUpdate(tpf: Float) {
- }
-
-
- private def createSky(manager: AssetManager): Spatial = {
- val west = manager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg");
- val east = manager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg");
- val north = manager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg");
- val south = manager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg");
- val up = manager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg");
- val down = manager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg");
-
- val sky = SkyFactory.createSky(manager, west, east, north, south, up, down);
- sky
- }
-
-}
-
View
13 src/main/scala/org/skycastle/client/engine/Engine.scala
@@ -0,0 +1,13 @@
+package org.skycastle.client.engine
+
+import com.jme3.asset.AssetManager
+import org.skycastle.utils.Service
+
+/**
+ * The 3D display engine.
+ */
+trait Engine extends Service {
+
+ def getAssetManager: AssetManager
+
+}
View
172 ...la/org/skycastle/client/ClipmapTerrainSpike.scala → ...cala/org/skycastle/client/engine/EngineImpl.scala
@@ -1,91 +1,50 @@
-package org.skycastle.client
+package org.skycastle.client.engine
import com.jme3.app.SimpleApplication
+import com.jme3.asset.plugins.FileLocator
+import com.jme3.app.state.ScreenshotAppState
+import org.skycastle.client.terrain.definition._
+import org.skycastle.client.terrain.view.{SimpleGroundLodStrategy, Ground, FunctionalTerrainBlockSource}
+import org.skycastle.client.sky.Sky
+import com.jme3.math.{ColorRGBA, Vector3f}
+import com.jme3.scene.{Node, Geometry}
+import com.jme3.scene.shape.Box
import com.jme3.material.Material
-import com.jme3.terrain.noise.fractal.FractalSum
-import com.jme3.terrain.noise.filter.{IterativeFilter, SmoothFilter, OptimizedErode, PerturbFilter}
-import com.jme3.post.FilterPostProcessor
import com.jme3.system.AppSettings
-import com.jme3.app.Application._
-import com.jme3.app.SimpleApplication._
-import com.jme3.app.state.ScreenshotAppState
-import com.jme3.texture.Texture.WrapMode
+import com.jme3.texture.Texture
+import org.skycastle.client.terrain.definition.MaterialLayer
+import org.skycastle.client.terrain.definition.GroundMaterial
+import org.skycastle.client.terrain.definition.MountainFun
+import org.skycastle.client.terrain.definition.TurbulenceFun
+import org.skycastle.client.terrain.definition.NoiseFun
+import org.skycastle.client.terrain.definition.FoundationLayer
+import org.skycastle.client.terrain.definition.GroundSizeSettings
import com.jme3.terrain.noise.basis.FilteredBasis
-import com.jme3.terrain.geomipmap.grid.FractalTileLoader
+import com.jme3.terrain.noise.fractal.FractalSum
+import org.skycastle.client.ClampingNoiseModulator
+import com.jme3.terrain.noise.filter.{IterativeFilter, SmoothFilter, OptimizedErode, PerturbFilter}
import com.jme3.terrain.geomipmap.{TerrainLodControl, TerrainGrid, TerrainQuad}
+import com.jme3.terrain.geomipmap.grid.FractalTileLoader
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator
import com.jme3.asset.AssetManager
-import com.jme3.scene.{Geometry, Node, Spatial}
-import messaging.{Message, MessageHandler}
-import network.protocol.Message
-import network.{ServerHandler, ClientNetworkingImpl}
-import sky.Sky
-import terrain._
-import com.jme3.math.{ColorRGBA, Vector3f}
-import com.jme3.asset.plugins.FileLocator
-import definition._
-import com.jme3.scene.shape.{Sphere, Dome, Box}
-import org.skycastle.utils.Logging
-import com.jme3.texture.Texture
+import com.jme3.texture.Texture.WrapMode
+import com.jme3.post.FilterPostProcessor
import com.jme3.water.WaterFilter
-import view.FunctionalTerrainBlockSource
/**
- *
+ * JMonkey based 3D engine implementation.
*/
-object ClipmapTerrainSpike extends SimpleApplication {
+class EngineImpl extends SimpleApplication with Engine {
- private val waterOn = false
- private val wireframe = false
private val limitFps= true
- private val lightingOn = !waterOn
-
private val movementSpeed: Float = 400
+ private val lightingOn = true
private val startX = 0
private val startZ = 0
private val lightDir = new Vector3f(-4.9f, -1.3f, 5.9f)
- private var networking: ClientNetworking = null
-
- def main(args: Array[String]) {
- Logging.initializeLogging()
-
- networking = new ClientNetworking(new ServerHandler {
- def onConnected() {
- println("Connected")
- }
- def onDisconnected(reason: String, cause: Exception) {
- println("Disconnected")
- }
- def onMessage(message: Message) {
- println("Got message " + message)
- }
- def onConnectionFailed(reason: String, cause: Exception) {
- println("Connection failed " + reason + ": " + cause.getMessage)
- }
- })
-
- networking.setup()
-
- //networking.createAccount("localhost", 6283, "TestUser1", "testPass%31# 32sdf");
-// networking.login("localhost", 6283, "TestUser1", "testPass%31# 32sdf");
-
- val settings: AppSettings = new AppSettings(true)
- if (limitFps) {
- settings.setFrameRate(60)
- settings.setVSync(true)
- }
- else {
- settings.setFrameRate(-1)
- settings.setVSync(false)
- }
- setSettings(settings)
- start()
- }
-
- @Override
def simpleInitApp() {
assetManager.registerLocator("assets", classOf[FileLocator])
@@ -97,12 +56,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
this.stateManager.attach(new ScreenshotAppState())
// Terrain
- /*
- val terrainMaterial = createTerrainMaterial(assetManager, grassScale, dirtScale, rockScale)
- val groundFunction = createGround
- val terrain = createTerrain(groundFunction, terrainMaterial)
- */
- val terrainMaterial = if (wireframe) createWireframeMaterial(assetManager) else createSimpleTerrainMaterial(getAssetManager)
+ val terrainMaterial = createSimpleTerrainMaterial(getAssetManager)
// val block= new TerrainBlock(terrainMaterial, new TestTerrain(), 1000, 1000, 1000, 1000)
// val terrain = block.getGeometry(assetManager)
@@ -119,18 +73,6 @@ object ClipmapTerrainSpike extends SimpleApplication {
this.rootNode.attachChild(terrain)
- // Water
- if (waterOn) viewPort.addProcessor(createWater(assetManager, rootNode, lightDir, 0))
-
-
-
- // Sound
- // Chops on ubuntu 11.10
- /*
- val waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", false);
- waves.setLooping(true);
- audioRenderer.playSource(waves);
- */
// Sky
val sky = new Sky(getCamera, assetManager)
@@ -148,9 +90,33 @@ object ClipmapTerrainSpike extends SimpleApplication {
mat.setColor("Color", ColorRGBA.Red)
box.setMaterial(mat)
rootNode.attachChild(box)
+ }
+ override def startup() {
+ // Settings
+ val settings: AppSettings = new AppSettings(true)
+ if (limitFps) {
+ settings.setFrameRate(60)
+ settings.setVSync(true)
+ }
+ else {
+ settings.setFrameRate(-1)
+ settings.setVSync(false)
+ }
+ setSettings(settings)
+
+ // Start the 3D engine
+ start()
}
+ override def shutdown() {
+ // Stop the engine, wait until it is fully destroyed.
+ stop(true)
+ }
+
+
+
+
private def createTestTerrain: GroundDef = {
def createMaterial(name: Symbol, textureFile: String): GroundMaterial = {
val texture: Texture = assetManager.loadTexture(textureFile)
@@ -166,31 +132,31 @@ object ClipmapTerrainSpike extends SimpleApplication {
val groundDef: GroundDef = new GroundDef()
groundDef.addLayer(new FoundationLayer(-1.0, bedrock,
MountainFun(size = 1000000, altitude = 10000, sharpness = 4, offset=0.98213)
- - MountainFun(size = 50000, altitude = 7000, sharpness = 3, offset=0.9843211233)
- - NoiseFun(sizeScale = 10000, seed=342123, amplitude = 1000)))
+ - MountainFun(size = 50000, altitude = 7000, sharpness = 3, offset=0.9843211233)
+ - NoiseFun(sizeScale = 10000, seed=342123, amplitude = 1000)))
groundDef.addLayer(new MaterialLayer(0.0, stone,
//NoiseFun(sizeScale = 1000, seed=2356451, amplitude = 100)
MountainFun(size = 100000, altitude = 1000, sharpness = 4, offset=0.98213)
- + MountainFun(size = 1000, altitude = 100, sharpness = 2)
- + MountainFun(size = 10000, altitude = 1000, sharpness = 4, offset = 1.0123) ))
+ + MountainFun(size = 1000, altitude = 100, sharpness = 2)
+ + MountainFun(size = 10000, altitude = 1000, sharpness = 4, offset = 1.0123) ))
groundDef.addLayer(new MaterialLayer(0.5, sand,
//NoiseFun(sizeScale = 200, seed=453242, amplitude = 10) /*
TurbulenceFun(2, sizeX = 2000, sizeZ= 2000, amplitude = 20, offsetZ = 34123.123)
- + NoiseFun(sizeX= 21234, sizeZ= 12433, amplitude= 10, offsetZ = 32335.12)
- + NoiseFun(sizeX= 13412, sizeZ= 42313, amplitude= 5, offsetZ = 335.12)
- + MountainFun(size = 5100, altitude = 10, sharpness = 2, offset = 1.123)
- + NoiseFun(offsetX = 764.12, amplitude = 0.2, sizeX = 1.3f, sizeZ = 1)))
+ + NoiseFun(sizeX= 21234, sizeZ= 12433, amplitude= 10, offsetZ = 32335.12)
+ + NoiseFun(sizeX= 13412, sizeZ= 42313, amplitude= 5, offsetZ = 335.12)
+ + MountainFun(size = 5100, altitude = 10, sharpness = 2, offset = 1.123)
+ + NoiseFun(offsetX = 764.12, amplitude = 0.2, sizeX = 1.3f, sizeZ = 1)))
groundDef.addLayer(new MaterialLayer(1.0, grass,
//NoiseFun(sizeScale = 50, seed=123545, amplitude = 1) /*
TurbulenceFun(sizeX = 1000, sizeZ = 1000, amplitude = 2, offsetZ = 5423.123)
- + NoiseFun(offsetX = 1235.12, amplitude = 2, sizeX = 100, sizeZ = 200)
- + NoiseFun(offsetX = 2335.12, amplitude = 0.4, sizeX = 2, sizeZ = 2)
- - ConstFun(0.4) ))
+ + NoiseFun(offsetX = 1235.12, amplitude = 2, sizeX = 100, sizeZ = 200)
+ + NoiseFun(offsetX = 2335.12, amplitude = 0.4, sizeX = 2, sizeZ = 2)
+ - ConstFun(0.4) ))
groundDef
}
- def createGround: FilteredBasis = {
+ private def createGround: FilteredBasis = {
val base = new FractalSum();
base.setRoughness(0.7f);
base.setFrequency(1.0f);
@@ -232,7 +198,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
ground
}
- def createTerrain(ground: FilteredBasis, material: Material): TerrainQuad = {
+ private def createTerrain(ground: FilteredBasis, material: Material): TerrainQuad = {
val patchSize: Int = 32 + 1
val maxVisibleSize: Int = 128 + 1
val terrain = new TerrainGrid("terrain", patchSize, maxVisibleSize, new FractalTileLoader(ground, 256f));
@@ -247,7 +213,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
terrain
}
- def createSimpleTerrainMaterial(assetManager: AssetManager): Material = {
+ private def createSimpleTerrainMaterial(assetManager: AssetManager): Material = {
//val texture1: Texture = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg")
val texture1: Texture = assetManager.loadTexture("textures/twisty_grass.png")
val texture2: Texture = assetManager.loadTexture("textures/regolith.png")
@@ -273,7 +239,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
mat_terrain
}
- def createWireframeMaterial(assetManager: AssetManager): Material = {
+ private def createWireframeMaterial(assetManager: AssetManager): Material = {
val mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")
mat.setColor("Color", ColorRGBA.Green)
@@ -282,7 +248,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
mat
}
- def createTerrainMaterial(assetManager: AssetManager, grassScale: Float, dirtScale: Float, rockScale: Float): Material = {
+ private def createTerrainMaterial(assetManager: AssetManager, grassScale: Float, dirtScale: Float, rockScale: Float): Material = {
// TERRAIN TEXTURE material
val mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md")
@@ -325,7 +291,7 @@ object ClipmapTerrainSpike extends SimpleApplication {
mat_terrain
}
- def createWater(assetManager: AssetManager, rootNode: Node, lightDir: Vector3f, initialWaterHeight: Float): FilterPostProcessor = {
+ private def createWater(assetManager: AssetManager, rootNode: Node, lightDir: Vector3f, initialWaterHeight: Float): FilterPostProcessor = {
val water = new WaterFilter(rootNode, lightDir)
water.setWaterHeight(initialWaterHeight)
//water.setSpeed(0.6f)
@@ -344,6 +310,4 @@ object ClipmapTerrainSpike extends SimpleApplication {
override def simpleUpdate(tpf: Float) {
}
-
}
-
View
31 src/main/scala/org/skycastle/client/entity/Appearance.scala
@@ -0,0 +1,31 @@
+package org.skycastle.client.entity
+
+import org.skycastle.client.ClientServices
+import com.jme3.scene.Spatial
+
+/**
+ *
+ */
+trait Appearance {
+
+ private var spatial: Spatial = null
+
+ /**
+ * Called to update
+ * @param props
+ */
+ def updateVisualState(props: Map[Symbol, Any])
+
+ /**
+ * @return the spatial for this appearance instance.
+ */
+ def getSpatial(services: ClientServices): Spatial = {
+ if (spatial == null) spatial = createSpatial(services)
+ spatial
+ }
+
+ // TODO: Also getter for collision shape?
+
+ protected def createSpatial(services: ClientServices): Spatial
+
+}
View
25 src/main/scala/org/skycastle/client/entity/Entity.scala
@@ -0,0 +1,25 @@
+package org.skycastle.client.entity
+
+/**
+ * Some usually visible in-game object.
+ *
+ * Has appearance, location.
+ * Affordances:
+ * - possible to pick up / carry
+ * - pushable, pullable, movable
+ * - climbable
+ * - list of possible work projects that can be started on the item
+ * - e.g. cut tree, dig up tree (for replanting), open door, unlock door, cut open door, etc.
+ * - attackable
+ * - Could inherit affordances from some common sets.
+ * - whether it has any interface that can be controlled
+ *
+ */
+case class Entity(id: Symbol,
+ appearance: Appearance,
+ location: Location) {
+
+
+
+
+}
View
14 src/main/scala/org/skycastle/client/entity/EntityService.scala
@@ -0,0 +1,14 @@
+package org.skycastle.client.entity
+
+import org.skycastle.utils.Service
+
+/**
+ *
+ */
+trait EntityService extends Service {
+
+ def createEntity(regionId: Symbol, entityId: Symbol, data: Map[Symbol, Any]): Entity
+
+ def updateEntity(entity: Entity, change: Map[Symbol, Any])
+
+}
View
23 src/main/scala/org/skycastle/client/entity/EntityServiceImpl.scala
@@ -0,0 +1,23 @@
+package org.skycastle.client.entity
+
+import org.skycastle.utils.ParameterChecker
+
+/**
+ *
+ */
+class EntityServiceImpl extends EntityService {
+
+ def createEntity(regionId: Symbol, entityId: Symbol, data: Map[Symbol, Any]): Entity = {
+ ParameterChecker.requireIsIdentifier(entityId, 'entityId)
+
+ // TODO: Extract data
+
+ new Entity(entityId, new PlaceholderAppearance(), new Location(regionId))
+ }
+
+ def updateEntity(entity: Entity, change: Map[Symbol, Any]) {
+ ParameterChecker.requireNotNull(entity, 'entity)
+
+ // TODO: Update entity
+ }
+}
View
10 src/main/scala/org/skycastle/client/entity/Location.scala
@@ -0,0 +1,10 @@
+package org.skycastle.client.entity
+
+import com.jme3.math.Vector3f
+
+/**
+ *
+ */
+case class Location(regionId: Symbol, pos: Vector3f = new Vector3f(), vel: Vector3f = new Vector3f()) {
+
+}
View
26 src/main/scala/org/skycastle/client/entity/PlaceholderAppearance.scala
@@ -0,0 +1,26 @@
+package org.skycastle.client.entity
+
+import org.skycastle.client.ClientServices
+import com.jme3.scene.{Geometry, Spatial}
+import com.jme3.scene.shape.Sphere
+import com.jme3.material.Material
+import com.jme3.math.ColorRGBA
+
+/**
+ *
+ */
+case class PlaceholderAppearance(radius: Float = 1, color: ColorRGBA = ColorRGBA.Red) extends Appearance {
+
+ def updateVisualState(props: Map[Symbol, Any]) {}
+
+ protected def createSpatial(services: ClientServices): Spatial = {
+ val sphere: Sphere = new Sphere(10, 10, radius)
+
+ val material: Material = new Material(services.engine.getAssetManager, "Common/MatDefs/Misc/Unshaded.j3md")
+ material.setColor("color", color)
+
+ val geometry: Geometry = new Geometry("placeholder", sphere)
+ geometry.setMaterial(material)
+ geometry
+ }
+}
View
2  src/main/scala/org/skycastle/client/messaging/MessageHandler.scala
@@ -1,8 +1,6 @@
package org.skycastle.client.messaging
import org.skycastle.utils.Service
-import org.skycastle.client.{Service, messaging}
-import messaging.Message
/**
* Something that receives messages or other connection info from a server, and handles them.
View
58 src/main/scala/org/skycastle/client/messaging/MessageHandlerImpl.scala
@@ -1,18 +1,60 @@
package org.skycastle.client.messaging
-import org.skycastle.client.ClientServices
+import handlers.{MethodActionHandler, ActionHandler}
+import org.skycastle.client.{ActionMethod, ClientServices}
+import org.skycastle.utils.{Logging}
+import com.thoughtworks.paranamer.CachingParanamer
/**
- *
+ * A message handler that delegates messages to methods of services that are annotated to be callable with message.
*/
-// TODO: Allow delegating messages to services, where they can call methods that are annotated to be callable with message.
-class MessageHandlerImpl(services: ClientServices) extends MessageHandler {
+class MessageHandlerImpl(services: ClientServices) extends MessageHandler with Logging {
- def onConnectionFailed(reason: String, cause: Exception) {}
+ private val paranamer = new CachingParanamer()
+ private var handlers: Map[Symbol, ActionHandler] = Map()
- def onConnected() {}
+ def onMessage(message: Message) {
+ handlers.get(message.action) match {
+ case Some(handlerMethod: ActionHandler) =>
+ try {
+ handlerMethod.handle(message)
+ } catch {
+ case e: Error =>
+ log.warn("MESSAGE_HANDLER: Error when handling message '"+message+"': " + e.getMessage, e)
+ case e: Exception =>
+ log.warn("MESSAGE_HANDLER: Exception when handling message '"+message+"': " + e.getMessage, e)
+ }
+ case None =>
+ log.warn("MESSAGE_HANDLER: Unknown action '"+message.action.name+"', for message '"+message+"', ignoring it.")
+ }
+ }
+
+ def onDisconnected(reason: String, cause: Exception) {
+ log.info("Disconnected from server: " + reason, cause)
+ }
+
+ def onConnectionFailed(reason: String, cause: Exception) {
+ log.error("Connected failed: " + reason, cause)
+ }
+
+ def onConnected() {
+ log.info("Connected to server")
+ }
+
+
+ override def startup() {
+ // Find any message handler methods in any services
+ services.services foreach {service =>
+ val serviceClass = service.getClass
+ serviceClass.getMethods foreach {method =>
+ val handlerAnnotation: ActionMethod = method.getAnnotation(classOf[ActionMethod])
+ if (handlerAnnotation != null) {
+ val actionName = Symbol(method.getName)
+ handlers += actionName -> MethodActionHandler(actionName, service, method, paranamer)
+ }
+ }
+ }
+ }
- def onMessage(message: Message) {}
- def onDisconnected(reason: String, cause: Exception) {}
}
View
14 src/main/scala/org/skycastle/client/messaging/handlers/ActionHandler.scala
@@ -0,0 +1,14 @@
+package org.skycastle.client.messaging.handlers
+
+import org.skycastle.client.messaging.Message
+
+/**
+ * Handler for some type of actions.
+ */
+trait ActionHandler {
+
+ def actionName: Symbol
+
+ def handle(message: Message)
+
+}
View
27 src/main/scala/org/skycastle/client/messaging/handlers/MethodActionHandler.scala
@@ -0,0 +1,27 @@
+package org.skycastle.client.messaging.handlers
+
+import com.thoughtworks.paranamer.Paranamer
+import java.lang.reflect.Method
+import org.skycastle.client.messaging.Message
+
+/**
+ * Action handler that invokes a method.
+ */
+case class MethodActionHandler(actionName: Symbol, host: AnyRef, method: Method, paranamer: Paranamer) extends ActionHandler {
+
+ val parameterNames: Array[Symbol] = extractParameterNames
+
+ def handle(message: Message) {
+ val paramValues = parameterNames map {
+ name => message.parameters.getOrElse(name, throw new Error("No value specified for handler method parameter '" + name.name + "' in the message."))
+ }
+ method.invoke(host, paramValues)
+ }
+
+ private def extractParameterNames: Array[Symbol] = {
+ paranamer.lookupParameterNames(method) map {
+ name => Symbol(name)
+ }
+ }
+
+}
View
1  src/main/scala/org/skycastle/client/network/ClientNetworking.scala
@@ -2,7 +2,6 @@ package org.skycastle.client.network
import org.skycastle.client.messaging.Message
import org.skycastle.utils.Service
-import org.skycastle.client.Service
/**
* Interface for client side networking.
View
9 src/main/scala/org/skycastle/client/network/ClientNetworkingImpl.scala
@@ -2,16 +2,13 @@ package org.skycastle.client.network
import org.apache.mina.transport.socket.nio.NioSocketConnector
import protocol.binary.BinaryProtocol
-import org.skycastle.client.messaging.{Message, MessageHandler}
-import protocol.Message
-import org.apache.mina.core.session.{IdleStatus, IoSession}
+import org.skycastle.client.messaging.Message
+import org.apache.mina.core.session.IoSession
import java.net.InetSocketAddress
import org.skycastle.utils.Logging
import org.apache.mina.filter.codec.ProtocolCodecFilter
import org.apache.mina.filter.logging.LoggingFilter
-import org.apache.mina.core.service.{IoHandlerAdapter, IoHandler}
-import com.sun.deploy.util.ArrayUtil
-import java.util.Arrays
+import org.apache.mina.core.service.IoHandlerAdapter
import org.skycastle.client.messaging.MessageHandler
/**
View
2  src/main/scala/org/skycastle/client/network/protocol/binary/BinaryProtocol.scala
@@ -2,7 +2,7 @@ package org.skycastle.client.network.protocol.binary
import _root_.org.apache.mina.core.buffer.IoBuffer
import org.skycastle.client.messaging.Message
-import org.skycastle.client.network.protocol.{MessageProtocol, Message}
+import org.skycastle.client.network.protocol.{MessageProtocol}
/**
View
1  src/main/scala/org/skycastle/client/network/protocol/binary/BinarySerializer.scala
@@ -4,7 +4,6 @@ import org.apache.mina.core.buffer.IoBuffer
import java.nio.charset.Charset
import org.skycastle.utils.Logging
import org.skycastle.client.messaging.Message
-import org.skycastle.client.network.protocol.Message
import org.skycastle.client.network.EntityId
View
19 src/main/scala/org/skycastle/client/region/Region.scala
@@ -0,0 +1,19 @@
+package org.skycastle.client.region
+
+import org.skycastle.client.entity.Entity
+
+
+/**
+ *
+ */
+trait Region {
+
+ def addEntity(entity: Entity)
+
+ def getEntity(entityId: Symbol): Entity
+
+ def removeEntity(entityId: Symbol)
+ def removeAll()
+
+
+}
View
37 src/main/scala/org/skycastle/client/region/RegionImpl.scala
@@ -0,0 +1,37 @@
+package org.skycastle.client.region
+
+import org.skycastle.client.entity.Entity
+import java.util
+import org.skycastle.utils.ParameterChecker
+
+/**
+ *
+ */
+class RegionImpl(regionId: Symbol) extends Region {
+
+ private val entities = new util.HashMap[Symbol, Entity]()
+
+ def addEntity(entity: Entity) {
+ ParameterChecker.requireNotNull(entity, 'entity)
+
+ entities.put(entity.id, entity)
+ }
+
+ def getEntity(entityId: Symbol): Entity = {
+ ParameterChecker.requireNotNull(entityId, 'entityId)
+ if (!entities.containsKey(entityId)) throw new Error("No entity with id '"+entityId.name+"' found in the region")
+
+ entities.get(entityId)
+ }
+
+ def removeEntity(entityId: Symbol) {
+ ParameterChecker.requireNotNull(entityId, 'entityId)
+
+ entities.remove(entityId)
+ }
+
+ def removeAll() {
+ entities.clear()
+ }
+
+}
View
56 src/main/scala/org/skycastle/client/region/RegionService.scala
@@ -1,6 +1,8 @@
package org.skycastle.client.region
-import javax.vecmath.Matrix4f
+import org.skycastle.client.ActionMethod
+import org.skycastle.utils.Service
+
/**
* A region is a space that uses an own coordinate system, and which is typically managed by just one server.
@@ -22,12 +24,40 @@ import javax.vecmath.Matrix4f
*/
// TODO: Maybe most practical if portals between regions are special entities?
// TODO: For maximum non-navigability, make region id:s random when they appear, maintain mapping on server side.
-trait RegionService {
+trait RegionService extends Service {
+
+ /**
+ * @return the currently active region.
+ */
+ def currentRegion: Region
+
+ def getRegion(regionId: Symbol): Region
+
+ /**
+ * @return the currently available regions.
+ */
+ def regions: Map[Symbol, Region]
+
+ /**
+ * Indicates that a new region is visible.
+ * Visible entities in the region will be specified with entityAppearance messages.
+ * @param regionId
+ * @param regionData TODO: Should contain some basic info about the region, if needed?
+ */
+ @ActionMethod
+ def regionAppeared(regionId: Symbol, regionData: Any)
+
+ /**
+ * Indicates that a region is no longer visible. Any entities located in it are no longer visible either.
+ */
+ @ActionMethod
+ def regionDisappeared(regionId: Symbol)
/**
* Called when the region that the actively controlled player character is in changed.
* @param regionId the id of the new current region.
*/
+ @ActionMethod
def currentRegionChanged(regionId: Symbol)
/**
@@ -44,26 +74,26 @@ trait RegionService {
// The higher the density / proximity, the higher the slowdown, up to some max (so after finding the 5 closest persons no point in finding more,
// as it would not change the slowdown - or just keep track of nr of people / softly blocking things in a tile) - also slower to walk towards someone than away from them.
// Same approach can be used for thick under-vegetation, branches, etc)
- def entityAppeared(regionId: Symbol, entityId: String, entityData: Any)
+ @ActionMethod
+ def entityAppeared(regionId: Symbol, entityId: Symbol, entityData: Map[Symbol, Any])
/**
- * Called when an entity is no longer perceivable.
+ * Called when an entity moves from one region to another.
*/
- def entityDisappeared(regionId: Symbol, entityId: String)
-
+ @ActionMethod
+ def entityChangedRegion(oldRegionId: Symbol, newRegionId: Symbol, entityId: Symbol)
/**
- * Indicates that a new region is visible.
- * Visible entities in the region will be specified with entityAppearance messages.
- * @param regionId
- * @param regionData TODO: Should contain some basic info about the region, if needed?
+ * Called when an entity changes in some way.
*/
- def regionAppeared(regionId: Symbol, regionData: Any)
+ @ActionMethod
+ def entityUpdated(regionId: Symbol, entityId: Symbol, changeData: Map[Symbol, Any])
/**
- * Indicates that a region is no longer visible. Any entities located in it are no longer visible either.
+ * Called when an entity is no longer perceivable.
*/
- def regionDisappeared(regionId: Symbol)
+ @ActionMethod
+ def entityDisappeared(regionId: Symbol, entityId: Symbol)
}
View
66 src/main/scala/org/skycastle/client/region/RegionServiceImpl.scala
@@ -0,0 +1,66 @@
+package org.skycastle.client.region
+
+import org.skycastle.client.ClientServices
+import org.skycastle.utils.ParameterChecker
+
+/**
+ *
+ */
+class RegionServiceImpl(services: ClientServices) extends RegionService {
+
+ var regions: Map[Symbol, Region] = Map()
+ var currentRegion: Region = null
+
+
+ def getRegion(regionId: Symbol): Region = {
+ ParameterChecker.requireNotNull(regionId, 'regionId)
+ if (!regions.contains(regionId)) throw new Error("No region named '"+regionId.name+"' found")
+
+ regions(regionId)
+ }
+
+ def currentRegionChanged(regionId: Symbol) {
+ currentRegion = getRegion(regionId)
+ }
+
+ def entityAppeared(regionId: Symbol, entityId: Symbol, entityData: Map[Symbol, Any]) {
+ val region = getRegion(regionId)
+ val entity = services.entityService.createEntity(regionId, entityId, entityData)
+ region.addEntity(entity)
+ }
+
+ def entityChangedRegion(oldRegionId: Symbol, newRegionId: Symbol, entityId: Symbol) {
+ val oldRegion = getRegion(oldRegionId)
+ val newRegion = getRegion(newRegionId)
+
+ val entity = oldRegion.getEntity(entityId)
+
+ oldRegion.removeEntity(entityId)
+ newRegion.addEntity(entity)
+ }
+
+ def entityUpdated(regionId: Symbol, entityId: Symbol, changeData: Map[Symbol, Any]) {
+ val region = getRegion(regionId)
+ val entity = region.getEntity(entityId)
+ services.entityService.updateEntity(entity, changeData)
+ }
+
+ def entityDisappeared(regionId: Symbol, entityId: Symbol) {
+ val region = getRegion(regionId)
+ region.removeEntity(entityId)
+ }
+
+ def regionAppeared(regionId: Symbol, regionData: Any) {
+ ParameterChecker.requireIsIdentifier(regionId, 'regionId)
+ if (regions.contains(regionId)) throw new Error("A region with id '"+regionId+"' already exists.")
+
+ val region = new RegionImpl(regionId)
+ regions += regionId -> region
+ }
+
+ def regionDisappeared(regionId: Symbol) {
+ val region = getRegion(regionId)
+ region.removeAll()
+ regions -= regionId
+ }
+}
View
8 src/main/scala/org/skycastle/client/terrain/TerrainServiceImpl.scala
@@ -1,8 +0,0 @@
-package org.skycastle.client.terrain
-
-/**
- *
- */
-class TerrainServiceImpl extends TerrainService {
-
-}
View
4 src/main/scala/org/skycastle/client/terrain/view/FunctionalTerrainBlockSource.scala
@@ -1,11 +1,9 @@
package org.skycastle.client.terrain.view
import com.jme3.material.Material
-import definition.{GroundSizeSettings, GroundDef}
import com.jme3.asset.AssetManager
import org.skycastle.client.terrain.definition.{GroundSizeSettings, GroundDef}
-import org.skycastle.client.terrain.view.TerrainBlockSource
-import org.skycastle.client.terrain.{BlockPos, TerrainBlockSource}
+import org.skycastle.client.terrain.BlockPos
/**
*
View
3  src/main/scala/org/skycastle/client/terrain/view/Ground.scala
@@ -4,11 +4,12 @@ import com.jme3.asset.AssetManager
import com.jme3.scene.Node
import com.jme3.renderer.Camera
import com.jme3.math.Vector3f
-import definition.GroundDef
import javax.vecmath.Vector3d
import scala.collection.JavaConversions._
import org.skycastle.utils.MathUtils
import java.util.{Collections, HashSet, ArrayList, HashMap}
+import org.skycastle.client.terrain.definition.{GroundDef, GroundSizeSettings}
+import org.skycastle.client.terrain.BlockPos
/**
*
View
5 src/main/scala/org/skycastle/client/terrain/view/GroundLodStrategy.scala
@@ -1,9 +1,8 @@
package org.skycastle.client.terrain.view
-import org.skycastle.client.terrain.definition
-import definition.GroundDef
+import org.skycastle.client.terrain.{BlockPos, definition}
+import definition.{GroundSizeSettings, GroundDef}
import javax.vecmath.Vector3d
-import java.util.{HashSet, HashMap}
/**
* Check whether to split or merge or do nothing for a block at a specific level of detail and position, given the camera position.
View
4 src/main/scala/org/skycastle/client/terrain/view/GroundTree.scala
@@ -1,12 +1,10 @@
package org.skycastle.client.terrain.view
import com.jme3.scene.Node
-import definition.{GroundSizeSettings, GroundDef}
import scala.collection.JavaConversions._
import javax.vecmath.Vector3d
import com.jme3.asset.AssetManager
-import org.skycastle.client.terrain.view.TerrainBlockSource
-import org.skycastle.client.terrain.{TerrainBlockSource, BlockPos}
+import org.skycastle.client.terrain.BlockPos
import org.skycastle.client.terrain.definition.{GroundSizeSettings, GroundDef}
/**
View
3  src/main/scala/org/skycastle/client/terrain/view/SimpleGroundLodStrategy.scala
@@ -1,9 +1,10 @@
package org.skycastle.client.terrain.view
-import definition.GroundDef
import javax.vecmath.Vector3d
import org.skycastle.utils.MathUtils
import java.util.HashSet
+import org.skycastle.client.terrain.{BlockPosCache, BlockPos}
+import org.skycastle.client.terrain.definition.{GroundSizeSettings, GroundDef}
/**
*
View
7 src/main/scala/org/skycastle/client/terrain/view/TerrainBlock.scala
@@ -4,13 +4,12 @@ import com.jme3.scene.VertexBuffer.Type
import com.jme3.util.BufferUtils
import com.jme3.material.Material
import com.jme3.asset.AssetManager
-import definition.{GroundDef, GroundMaterial}
-import javax.vecmath.Vector3d
import com.jme3.scene.{Node, Spatial, Geometry, Mesh}
import com.jme3.texture.Texture
-import com.jme3.math.{Vector4f, Vector3f, ColorRGBA, Vector2f}
-import java.nio.FloatBuffer
+import com.jme3.math.{Vector3f, Vector2f}
import java.util._
+import org.skycastle.client.terrain.BlockPos
+import org.skycastle.client.terrain.definition.{GroundMaterial, GroundSizeSettings, GroundDef}
/**
*
View
2  src/main/scala/org/skycastle/utils/Services.scala
@@ -24,7 +24,7 @@ trait Services {
* @return the added service.
*/
protected def addService[T <: Service](service: T): T = {
- _services ::= List(service)
+ _services :::= List(service)
service
}
Please sign in to comment.
Something went wrong with that request. Please try again.