diff --git a/src/Marble.hx b/src/Marble.hx index 1871271e..ae9c552e 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -323,6 +323,8 @@ class Marble extends GameObject { public var cubemapRenderer:CubemapRenderer; + var shadowVolume:h3d.scene.Mesh; + var connection:GameConnection; var moveMotionDir:Vector; var lastMove:Move; @@ -398,9 +400,10 @@ class Marble extends GameObject { var matWorker = new ResourceLoaderWorker(() -> { marbleDts.init(null, () -> {}); // SYNC for (mat in marbleDts.materials) { - mat.castShadows = true; - mat.shadows = true; + mat.castShadows = false; + mat.shadows = false; mat.receiveShadows = false; + mat.mainPass.setPassName("marble"); // mat.mainPass.culling = None; if (Settings.optionsSettings.reflectionDetail > 0) { @@ -488,6 +491,7 @@ class Marble extends GameObject { mat.castShadows = true; mat.shadows = true; mat.receiveShadows = false; + mat.mainPass.setPassName("marble"); } } } @@ -519,6 +523,10 @@ class Marble extends GameObject { this.addChild(marbleDts); + buildShadowVolume(); + if (level != null) + level.scene.addChild(this.shadowVolume); + // var geom = Sphere.defaultUnitSphere(); // geom.addUVs(); // var marbleTexture = ResourceLoader.getFileEntry("data/shapes/balls/base.marble.png").toTexture(); @@ -568,6 +576,80 @@ class Marble extends GameObject { matWorker.run(); } + function buildShadowVolume() { + var idx = new hxd.IndexBuffer(); + // slanted part of cone + var circleVerts = 32; + for (i in 1...circleVerts) { + idx.push(0); + idx.push(i + 1); + idx.push(i); + } + // connect to start + idx.push(0); + idx.push(1); + idx.push(circleVerts); + + // base of cone + for (i in 1...circleVerts - 1) { + idx.push(1); + idx.push(i + 1); + idx.push(i + 2); + } + var pts = []; + pts.push(new h3d.col.Point(0, 0, -7.0)); + + for (i in 0...circleVerts) { + var x = i / (circleVerts - 1) * (2 * Math.PI); + pts.push(new h3d.col.Point(Math.cos(x) * 0.2, -Math.sin(x) * 0.2, 0.0)); + } + var shadowPoly = new h3d.prim.Polygon(pts, idx); + shadowPoly.addUVs(); + shadowPoly.addNormals(); + shadowVolume = new h3d.scene.Mesh(shadowPoly, h3d.mat.Material.create()); + shadowVolume.material.castShadows = false; + shadowVolume.material.receiveShadows = false; + shadowVolume.material.shadows = false; + + var colShader = new h3d.shader.FixedColor(0x000026, 0.35); + + var shadowPass1 = shadowVolume.material.mainPass.clone(); + shadowPass1.setPassName("shadowPass1"); + shadowPass1.stencil = new h3d.mat.Stencil(); + shadowPass1.stencil.setFunc(Always, 1, 0xFF, 0xFF); + shadowPass1.depth(false, Less); + shadowPass1.setColorMask(false, false, false, false); + shadowPass1.culling = Back; + shadowPass1.stencil.setOp(Keep, Increment, Keep); + shadowPass1.addShader(colShader); + + var shadowPass2 = shadowVolume.material.mainPass.clone(); + shadowPass2.setPassName("shadowPass2"); + shadowPass2.stencil = new h3d.mat.Stencil(); + shadowPass2.stencil.setFunc(Always, 1, 0xFF, 0xFF); + shadowPass2.depth(false, Less); + shadowPass2.setColorMask(false, false, false, false); + shadowPass2.culling = Front; + shadowPass2.stencil.setOp(Keep, Decrement, Keep); + shadowPass2.addShader(colShader); + + var shadowPass3 = shadowVolume.material.mainPass.clone(); + shadowPass3.setPassName("shadowPass3"); + shadowPass3.stencil = new h3d.mat.Stencil(); + shadowPass3.stencil.setFunc(LessEqual, 1, 0xFF, 0xFF); + shadowPass3.depth(false, Less); + shadowPass3.culling = Front; + shadowPass3.stencil.setOp(Keep, Keep, Keep); + shadowPass3.blend(SrcAlpha, OneMinusSrcAlpha); + shadowPass3.addShader(colShader); + + shadowVolume.material.addPass(shadowPass1); + shadowVolume.material.addPass(shadowPass2); + shadowVolume.material.addPass(shadowPass3); + + shadowVolume.material.removePass(shadowVolume.material.mainPass); + } + function findContacts(collisionWorld:CollisionWorld, timeState:TimeState) { this.contacts = queuedContacts; CollisionPool.clear(); @@ -2213,6 +2295,12 @@ class Marble extends GameObject { } public function updatePowerupStates(timeState:TimeState) { + this.shadowVolume.setPosition(x, y, z); + this.shadowVolume.setScale(this._renderScale); + if (this.level == null) + return; + this.shadowVolume.setRotationQuat(this.level.getOrientationQuat(timeState.currentAttemptTime)); + if (!this.controllable && this.connection == null) return; if (isHelicopterEnabled(timeState)) { @@ -2266,9 +2354,10 @@ class Marble extends GameObject { if (!this.isNetUpdate) { if (this.controllable) AudioManager.playSound(ResourceLoader.getResource('data/sound/use_blast.wav', ResourceLoader.getAudio, this.soundResources)); - this.blastWave.doSequenceOnceBeginTime = this.level.timeState.timeSinceLoad; - this.blastUseTime = this.level.timeState.currentAttemptTime; } + this.blastWave.doSequenceOnceBeginTime = this.level.timeState.timeSinceLoad; + this.blastUseTime = this.level.timeState.currentAttemptTime; + this.blastTicks = 0; return true; } else { diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index b2ae2cb5..b780b54e 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -407,13 +407,6 @@ class MarbleWorld extends Scheduler { this.ambient = ambientColor; // ls.perPixelLighting = false; - var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap); - shadow.power = 1; - shadow.mode = Dynamic; - shadow.minDist = 0.1; - shadow.maxDist = 200; - shadow.bias = 0; - var sunlight = new DirLight(sunDirection, scene); sunlight.color = directionalColor; diff --git a/src/PreviewWorld.hx b/src/PreviewWorld.hx index 0d1ae273..e787c17b 100644 --- a/src/PreviewWorld.hx +++ b/src/PreviewWorld.hx @@ -120,13 +120,6 @@ class PreviewWorld extends Scheduler { // ls.shadowLight.setDirection(new Vector(0, 0, -1)); // ls.perPixelLighting = false; - var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap); - shadow.power = 1; - shadow.mode = Dynamic; - shadow.minDist = 0.1; - shadow.maxDist = 200; - shadow.bias = 0; - var sunlight = new DirLight(sunDirection, scene); sunlight.color = directionalColor; return; diff --git a/src/Renderer.hx b/src/Renderer.hx index 26387635..a45a32aa 100644 --- a/src/Renderer.hx +++ b/src/Renderer.hx @@ -18,7 +18,7 @@ class Renderer extends h3d.scene.Renderer { public var depth:h3d.pass.Base = new h3d.scene.fwd.Renderer.DepthPass(); public var normal:h3d.pass.Base = new h3d.scene.fwd.Renderer.NormalPass(); - public var shadow = new h3d.pass.DefaultShadowMap(1024); + public var shadow = new h3d.pass.DefaultShadowMap(1); var glowBuffer:h3d.mat.Texture; @@ -46,6 +46,12 @@ class Renderer extends h3d.scene.Renderer { copyPass = new h3d.pass.Copy(); sfxBuffer = new Texture(512, 512, [Target]); Window.getInstance().addResizeEvent(() -> onResize()); + shadow.autoShrink = false; + shadow.power = 0; + shadow.mode = Static; + shadow.minDist = 0.1; + shadow.maxDist = 0.1; + shadow.bias = 0; } public inline static function getSfxBuffer() { @@ -79,7 +85,7 @@ class Renderer extends h3d.scene.Renderer { override function getPassByName(name:String):h3d.pass.Base { if (name == "alpha" || name == "additive" || name == "glowPre" || name == "glow" || name == "refract" || name == "glowPreNoRender" - || name == "interior" || name == "zPass") + || name == "interior" || name == "zPass" || name == "marble" || name == "shadowPass1" || name == "shadowPass2" || name == "shadowPass3") return defaultPass; return super.getPassByName(name); } @@ -97,7 +103,7 @@ class Renderer extends h3d.scene.Renderer { if (!cubemapPass) { // we push the target separately ctx.engine.pushTarget(backBuffer); } - ctx.engine.clear(0, 1); + ctx.engine.clear(0, 1, 0); if (has("shadow")) renderPass(shadow, get("shadow")); @@ -140,6 +146,12 @@ class Renderer extends h3d.scene.Renderer { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 3) { renderPass(defaultPass, get("default")); } + + renderPass(defaultPass, get("shadowPass1")); + renderPass(defaultPass, get("shadowPass2")); + renderPass(defaultPass, get("shadowPass3")); + renderPass(defaultPass, get("marble")); + if (!cubemapPass) ProfilerUI.measure("glow", 0); if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) diff --git a/src/net/NetCommands.hx b/src/net/NetCommands.hx index 0d6a1047..405a2128 100644 --- a/src/net/NetCommands.hx +++ b/src/net/NetCommands.hx @@ -253,6 +253,10 @@ class NetCommands { Net.serverInfo.state = "LOBBY"; MasterServerClient.instance.sendServerInfo(Net.serverInfo); // notify the server of the playing state + var b = Net.sendPlayerInfosBytes(); + for (cc in Net.clients) { + cc.sendBytes(b); + } } }