mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 03:54:06 +09:00
circular (octagon actually) propagation of light
Former-commit-id: 1e67a3284ea298a0d8f27309d9d8ca800a8525c8 Former-commit-id: a5067df80d1053ceec6d78b6fda6cf0afa3c286c
This commit is contained in:
@@ -266,6 +266,8 @@ constructor() : BasicGameState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun changePossession(refid: Int) {
|
private fun changePossession(refid: Int) {
|
||||||
|
// TODO prevent possessing other player on multiplayer
|
||||||
|
|
||||||
if (!hasActor(refid)) {
|
if (!hasActor(refid)) {
|
||||||
throw IllegalArgumentException("No such actor in actorContainer: $refid")
|
throw IllegalArgumentException("No such actor in actorContainer: $refid")
|
||||||
}
|
}
|
||||||
@@ -309,12 +311,19 @@ constructor() : BasicGameState() {
|
|||||||
/////////////////
|
/////////////////
|
||||||
// --> Change of blend mode <-- introduced by ActorWithBody //
|
// --> Change of blend mode <-- introduced by ActorWithBody //
|
||||||
actorContainer.forEach { actor ->
|
actorContainer.forEach { actor ->
|
||||||
if (actor is ActorWithBody && actor.inScreen() && actor !is Player) {
|
if (actor is ActorWithBody && actor.inScreen() && actor !is Player && !actor.drawTopmost) {
|
||||||
actor.drawBody(gc, worldDrawFrameBuffer.graphics)
|
actor.drawBody(gc, worldDrawFrameBuffer.graphics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --> Change of blend mode <-- introduced by ActorWithBody //
|
// --> Change of blend mode <-- introduced by ActorWithBody //
|
||||||
player.drawBody(gc, worldDrawFrameBuffer.graphics)
|
player.drawBody(gc, worldDrawFrameBuffer.graphics)
|
||||||
|
// --> Change of blend mode <-- introduced by ActorWithBody //
|
||||||
|
actorContainer.forEach { actor ->
|
||||||
|
if (actor is ActorWithBody && actor.inScreen() && actor !is Player && actor.drawTopmost) {
|
||||||
|
actor.drawBody(gc, worldDrawFrameBuffer.graphics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --> Change of blend mode <-- introduced by ActorWithBody //
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ open class ActorWithBody : Actor() {
|
|||||||
|
|
||||||
/** !! ActorValue macros are on the very bottom of the source !! **/
|
/** !! ActorValue macros are on the very bottom of the source !! **/
|
||||||
|
|
||||||
|
|
||||||
override var actorValue: ActorValue = ActorValue()
|
override var actorValue: ActorValue = ActorValue()
|
||||||
|
|
||||||
@Transient internal var sprite: SpriteAnimation? = null
|
@Transient internal var sprite: SpriteAnimation? = null
|
||||||
@Transient internal var spriteGlow: SpriteAnimation? = null
|
@Transient internal var spriteGlow: SpriteAnimation? = null
|
||||||
|
|
||||||
var drawMode = BLEND_NORMAL
|
var drawMode = BLEND_NORMAL
|
||||||
|
/** for fake tiles. Draw on top of player(s) */
|
||||||
|
var drawTopmost = false
|
||||||
|
|
||||||
@Transient private val world: GameWorld = Terrarum.ingame.world
|
@Transient private val world: GameWorld = Terrarum.ingame.world
|
||||||
|
|
||||||
|
|||||||
@@ -183,31 +183,33 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
// O(36n) == O(n) where n is a size of the map.
|
// O(36n) == O(n) where n is a size of the map.
|
||||||
// Because of inevitable overlaps on the area, it only works with ADDITIVE blend (aka maxblend)
|
// Because of inevitable overlaps on the area, it only works with ADDITIVE blend (aka maxblend)
|
||||||
|
|
||||||
|
|
||||||
// Round 1
|
// Round 1
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
for (y in for_y_start - overscan_open..for_y_end) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
for (x in for_x_start - overscan_open..for_x_end) {
|
||||||
setLight(x, y, calculate(x, y))
|
setLight(x, y, calculate(x, y, 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round 2
|
// Round 2
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
for (x in for_x_start - overscan_open..for_x_end) {
|
||||||
setLight(x, y, calculate(x, y))
|
setLight(x, y, calculate(x, y, 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round 3
|
// Round 3
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
for (x in for_x_end + overscan_open downTo for_x_start) {
|
||||||
setLight(x, y, calculate(x, y))
|
setLight(x, y, calculate(x, y, 3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round 4
|
// Round 4
|
||||||
for (y in for_y_start - overscan_open..for_y_end) {
|
for (y in for_y_start - overscan_open..for_y_end) {
|
||||||
for (x in for_x_end + overscan_open downTo for_x_start) {
|
for (x in for_x_end + overscan_open downTo for_x_start) {
|
||||||
setLight(x, y, calculate(x, y))
|
setLight(x, y, calculate(x, y, 4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,9 +239,9 @@ object LightmapRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculate(x: Int, y: Int): Int = calculate(x, y, false)
|
private fun calculate(x: Int, y: Int, pass: Int): Int = calculate(x, y, pass, false)
|
||||||
|
|
||||||
private fun calculate(x: Int, y: Int, doNotCalculateAmbient: Boolean): Int {
|
private fun calculate(x: Int, y: Int, pass: Int, doNotCalculateAmbient: Boolean): Int {
|
||||||
// O(9n) == O(n) where n is a size of the map
|
// O(9n) == O(n) where n is a size of the map
|
||||||
// TODO devise multithreading on this
|
// TODO devise multithreading on this
|
||||||
|
|
||||||
@@ -279,56 +281,24 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
if (!doNotCalculateAmbient) {
|
if (!doNotCalculateAmbient) {
|
||||||
// calculate ambient
|
// calculate ambient
|
||||||
var ambient: Int = 0
|
/* + * +
|
||||||
var nearby: Int
|
* * @ *
|
||||||
for (yoff in -1..1) {
|
* + * +
|
||||||
for (xoff in -1..1) {
|
* sample ambient for eight points and apply attenuation for those
|
||||||
/**
|
* maxblend eight values and use it
|
||||||
* filter for 'v's as:
|
*/
|
||||||
* +-+-+-+
|
var ambient = 0
|
||||||
* |a|v|a|
|
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
||||||
* +-+-+-+
|
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
||||||
* |v| |v|
|
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
||||||
* +-+-+-+
|
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
|
||||||
* |a|v|a|
|
ambient = ambient maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
|
||||||
* +-+-+-+
|
ambient = ambient maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
|
||||||
*/
|
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y ) ?: 0, thisTileOpacity)
|
||||||
if (xoff != yoff && -xoff != yoff) {
|
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y ) ?: 0, thisTileOpacity)
|
||||||
// 'v' tiles
|
|
||||||
nearby = getLight(x + xoff, y + yoff) ?: 0
|
|
||||||
}
|
|
||||||
else if (xoff != 0 && yoff != 0) {
|
|
||||||
// 'a' tiles
|
|
||||||
nearby = darkenUniformInt(getLight(x + xoff, y + yoff) ?: 0, 12)
|
|
||||||
// mix some to have more 'spreading'
|
|
||||||
// so that light spreads in a shape of an octagon instead of a diamond
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nearby = 0 // exclude 'me' tile
|
|
||||||
}
|
|
||||||
|
|
||||||
ambient = ambient maxBlend nearby // keep base value as brightest nearby
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ambient = darkenColoured(ambient, thisTileOpacity) // get real ambient by appling opacity value
|
|
||||||
|
|
||||||
|
|
||||||
return lightLevelThis maxBlend ambient
|
return lightLevelThis maxBlend ambient
|
||||||
// mix and return lightlevel and ambient
|
|
||||||
/*val retLevel = lightLevelThis maxBlend ambient
|
|
||||||
// hack: make sure (3,3,3) become 0
|
|
||||||
return if (retLevel.rawR() < 4 && retLevel.rawG() < 4 && retLevel.rawB() < 4)
|
|
||||||
0
|
|
||||||
else
|
|
||||||
retLevel*/
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// hack: make sure (3,3,3) become 0
|
|
||||||
/*return if (lightLevelThis.rawR() < 4 && lightLevelThis.rawG() < 4 && lightLevelThis.rawB() < 4)
|
|
||||||
0
|
|
||||||
else
|
|
||||||
lightLevelThis*/
|
|
||||||
return lightLevelThis
|
return lightLevelThis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -482,6 +452,14 @@ object LightmapRenderer {
|
|||||||
return constructRGBFromFloat(r.clampZero(), g.clampZero(), b.clampZero())
|
return constructRGBFromFloat(r.clampZero(), g.clampZero(), b.clampZero())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scaleColour(data: Int, scale: Float): Int {
|
||||||
|
val r = data.r() * scale
|
||||||
|
val g = data.g() * scale
|
||||||
|
val b = data.b() * scale
|
||||||
|
|
||||||
|
return constructRGBFromFloat(r.clampOne(), g.clampOne(), b.clampOne())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add each channel's RGB value.
|
* Add each channel's RGB value.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user