From f69f9597657e2608869e290207e666e84ae65dce Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Tue, 13 Jun 2023 23:33:32 +0530 Subject: [PATCH] astrolabe and other stuff --- src/CameraController.hx | 9 +- src/DtsObject.hx | 80 ++++++++++++- src/GameObject.hx | 5 + src/InstanceManager.hx | 31 ++++- src/Macros.hx | 2 + src/MarbleWorld.hx | 4 +- src/Renderer.hx | 7 +- src/dts/DtsFile.hx | 244 ++++++++++++++++++++++++++++++++++++++ src/dts/KeyFrame.hx | 20 ++++ src/dts/ObjectState.hx | 1 + src/dts/Trigger.hx | 1 + src/shapes/Astrolabe.hx | 30 +++++ src/shapes/Checkpoint.hx | 49 ++++++++ src/shapes/RoundBumper.hx | 18 +-- src/shapes/Sky.hx | 1 + src/shapes/StartPad.hx | 8 ++ 16 files changed, 485 insertions(+), 25 deletions(-) create mode 100644 src/dts/KeyFrame.hx create mode 100644 src/shapes/Astrolabe.hx diff --git a/src/CameraController.hx b/src/CameraController.hx index 1338d045..1523a0c5 100644 --- a/src/CameraController.hx +++ b/src/CameraController.hx @@ -175,11 +175,10 @@ class CameraController extends Object { if (Settings.gamepadSettings.invertYAxis) cameraPitchDelta = -cameraPitchDelta; nextCameraPitch += 0.75 * 5 * cameraPitchDelta * dt * Settings.gamepadSettings.cameraSensitivity; - var cameraYawDelta = (Key.isDown(Settings.controlsSettings.camRight) ? 1 : 0) - - (Key.isDown(Settings.controlsSettings.camLeft) ? 1 : 0) + var cameraYawDelta = (Key.isDown(Settings.controlsSettings.camRight) ? 1 : 0) - (Key.isDown(Settings.controlsSettings.camLeft) ? 1 : 0) + Gamepad.getAxis(Settings.gamepadSettings.cameraXAxis); - if (Settings.gamepadSettings.invertXAxis) - cameraYawDelta = -cameraYawDelta; + if (Settings.gamepadSettings.invertXAxis) + cameraYawDelta = -cameraYawDelta; nextCameraYaw += 0.75 * 5 * cameraYawDelta * dt * Settings.gamepadSettings.cameraSensitivity; nextCameraPitch = Math.max(-Math.PI / 2 + Math.PI / 4, Math.min(Math.PI / 2 - 0.0001, nextCameraPitch)); @@ -241,7 +240,7 @@ class CameraController extends Object { var up = new Vector(0, 0, 1); up.transform(orientationQuat.toMatrix()); var directionVector = new Vector(1, 0, 0); - var cameraVerticalTranslation = new Vector(0, 0, 0.3); + var cameraVerticalTranslation = new Vector(0, 0, 0.325); var q1 = new Quat(); q1.initRotateAxis(0, 1, 0, CameraPitch); diff --git a/src/DtsObject.hx b/src/DtsObject.hx index b90c85e8..2cb0c2ac 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -79,6 +79,7 @@ typedef SkinMeshData = { @:publicFields class DtsObject extends GameObject { var dtsPath:String; + var sequencePath:String; var directoryPath:String; var dts:DtsFile; var dtsResource:Resource; @@ -91,9 +92,14 @@ class DtsObject extends GameObject { var sequenceKeyframeOverride:Map = new Map(); var lastSequenceKeyframes:Map = new Map(); + var doSequenceOnce:Bool; + var doSequenceOnceBeginTime:Float; var graphNodes:Array = []; var dirtyTransforms:Array = []; + var meshVisibilities:Array = []; + var meshToIndex:Map = []; + var meshes:Array = []; var useInstancing:Bool = true; var isTSStatic:Bool; @@ -113,7 +119,7 @@ class DtsObject extends GameObject { var alphaShader:AlphaMult; var ambientRotate = false; - var ambientSpinFactor = -1 / 3 * Math.PI * 2; + var ambientSpinFactor = -1 / 6 * Math.PI * 2; public var idInLevel:Int = -1; @@ -125,6 +131,8 @@ class DtsObject extends GameObject { this.dtsResource = ResourceLoader.loadDts(this.dtsPath); this.dtsResource.acquire(); this.dts = this.dtsResource.resource; + if (this.sequencePath != null) + this.dts.importSequences(this.sequencePath); this.directoryPath = Path.directory(this.dtsPath); if (level != null) @@ -145,6 +153,11 @@ class DtsObject extends GameObject { graphNodes.push(new Object()); } + for (i in 0...this.dts.objects.length) { + meshes.push(null); + meshVisibilities.push(1); + } + for (i in 0...this.dts.nodes.length) { var node = this.dts.nodes[i]; if (node.parent != -1) { @@ -206,6 +219,7 @@ class DtsObject extends GameObject { poly.texMatNormals = geometry[k].texNormals.map(x -> x.toPoint()); var obj = new Mesh(poly, materials[k], this.graphNodes[i]); + meshToIndex.set(obj, dts.objects.indexOf(object)); } } else { var usedMats = []; @@ -218,9 +232,12 @@ class DtsObject extends GameObject { for (k in usedMats) { var obj = new Object(this.graphNodes[i]); + meshToIndex.set(obj, dts.objects.indexOf(object)); } } } + + meshes[dts.objects.indexOf(object)] = graphNodes[i]; } } @@ -375,6 +392,8 @@ class DtsObject extends GameObject { for (i in 0...dts.matNames.length) { var matName = matNameOverride.exists(dts.matNames[i]) ? matNameOverride.get(dts.matNames[i]) : this.dts.matNames[i]; + if (matName.indexOf('/') != -1) + matName = matName.substring(matName.lastIndexOf('/')); var flags = dts.matFlags[i]; var fullNames = ResourceLoader.getFullNamesOf(this.directoryPath + '/' + matName).filter(x -> Path.extension(x) != "dts"); var fullName = fullNames.length > 0 ? fullNames[0] : null; @@ -948,8 +967,12 @@ class DtsObject extends GameObject { var rot = sequence.rotationMatters.length > 0 ? sequence.rotationMatters[0] : 0; var trans = sequence.translationMatters.length > 0 ? sequence.translationMatters[0] : 0; var scale = sequence.scaleMatters.length > 0 ? sequence.scaleMatters[0] : 0; + var vis = sequence.visMatters.length > 0 ? sequence.visMatters[0] : 0; var affectedCount = 0; var completion = timeState.timeSinceLoad / sequence.duration; + if (doSequenceOnce) { + completion = Util.clamp((timeState.timeSinceLoad - doSequenceOnceBeginTime) / sequence.duration, 0, 0.98); + } var quaternions:Array = null; var translations:Array = null; @@ -961,7 +984,9 @@ class DtsObject extends GameObject { lastSequenceKeyframes.set(sequence, actualKeyframe); var keyframeLow = Math.floor(actualKeyframe); - var keyframeHigh = Math.ceil(actualKeyframe) % sequence.numKeyFrames; + var keyframeHigh = doSequenceOnce ? Math.ceil(actualKeyframe) : Math.ceil(actualKeyframe) % sequence.numKeyFrames; + if (doSequenceOnce && keyframeHigh >= sequence.numKeyFrames) + continue; var t = (actualKeyframe - keyframeLow) % 1; if (rot > 0) { @@ -1082,6 +1107,31 @@ class DtsObject extends GameObject { } } } + + affectedCount = 0; + var visIterIdx = 0; + if (vis > 0 && animateSubObjectOpacities) { + while (vis > 0) { + if (affectedCount >= this.dts.subshapes[0].numNodes) + break; + if (vis & 1 != 0) { + var v1 = this.dts.objectStates[sequence.baseObjectState + sequence.numKeyFrames * affectedCount + keyframeLow].vis; + var v2 = this.dts.objectStates[sequence.baseObjectState + sequence.numKeyFrames * affectedCount + keyframeHigh].vis; + + if (this.identifier == "RoundBumper") { + trace('Bumper: ${v1} ${v2}'); + } + var v = Util.lerp(v1, v2, t); + meshVisibilities[visIterIdx] = v; + updateSubObjectOpacity(visIterIdx); + affectedCount++; + } else { + meshVisibilities[visIterIdx] = this.dts.objectStates[visIterIdx].vis; + } + vis >>= 1; + visIterIdx++; + } + } } if (this.skinMeshData != null && !isInstanced) { @@ -1260,6 +1310,32 @@ class DtsObject extends GameObject { } } + function updateSubObjectOpacity(idx:Int) { + if (!this.useInstancing) { + var opacity = meshVisibilities[idx]; + var node = this.meshes[idx]; + if (node != null) { + for (ch in node.getMeshes()) { + for (pass in ch.material.getPasses()) { + var alphashader = pass.getShader(AlphaMult); + if (alphashader != null) + alphashader.alpha = opacity * this.currentOpacity; + else { + alphashader = new AlphaMult(); + alphashader.alpha = opacity * this.currentOpacity; + pass.addShader(alphashader); + } + } + } + } + } + } + + public override function getSubObjectOpacity(obj:Object):Float { + var idx = meshToIndex.get(obj); + return meshVisibilities[idx]; + } + public function setHide(hide:Bool) { if (hide) { this.setCollisionEnabled(false); diff --git a/src/GameObject.hx b/src/GameObject.hx index c3deaff6..8b8285fb 100644 --- a/src/GameObject.hx +++ b/src/GameObject.hx @@ -13,10 +13,15 @@ class GameObject extends Object { public var isCollideable:Bool = false; public var isBoundingBoxCollideable:Bool = false; public var enableCollideCallbacks:Bool = false; + public var animateSubObjectOpacities:Bool = false; var textureResources:Array> = []; var soundResources:Array> = []; + public function getSubObjectOpacity(obj:Object) { + return currentOpacity; + } + public function onMarbleContact(time:TimeState, ?contact:CollisionInfo) {} public function onMarbleInside(time:TimeState) {} diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 80250ea0..388a018b 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -70,8 +70,14 @@ class InstanceManager { minfo.meshbatch.begin(opaqueinstances.length); for (instance in opaqueinstances) { // Draw the opaque shit first var dtsShader = minfo.meshbatch.material.mainPass.getShader(DtsTexture); + var subOpacity = 1.0; if (dtsShader != null) { - dtsShader.currentOpacity = instance.gameObject.currentOpacity; + if (instance.gameObject.animateSubObjectOpacities) { + subOpacity = instance.gameObject.getSubObjectOpacity(instance.emptyObj); + minfo.meshbatch.shadersChanged = true; + } + + dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; } var transform = instance.emptyObj.getAbsPos(); minfo.meshbatch.material.mainPass.depthWrite = minfo.mesh.material.mainPass.depthWrite; @@ -89,6 +95,14 @@ class InstanceManager { minfo.meshbatch.material.mainPass.blendAlphaDst = minfo.mesh.material.mainPass.blendAlphaDst; minfo.meshbatch.material.mainPass.blendAlphaOp = minfo.mesh.material.mainPass.blendAlphaOp; + // handle the glow pass too + var glowPass = minfo.meshbatch.material.getPass("glow"); + if (glowPass != null) { + dtsShader = glowPass.getShader(DtsTexture); + if (dtsShader != null) + dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity; + } + minfo.meshbatch.emitInstance(); } } @@ -155,9 +169,12 @@ class InstanceManager { } for (shader in minfoshaders) minfo.meshbatch.material.mainPass.removeShader(shader); + var addshaders = []; for (shader in mat.mainPass.getShaders()) { - minfo.meshbatch.material.mainPass.addShader(shader); + addshaders.push(shader); } + for (shader in addshaders) + minfo.meshbatch.material.mainPass.addShader(shader); var glowPass = mat.getPass("glow"); if (glowPass != null) { var gpass = glowPass.clone(); @@ -180,9 +197,12 @@ class InstanceManager { } for (shader in minfoshaders) gpass.removeShader(shader); + var addshaders = []; for (shader in glowPass.getShaders()) { - gpass.addShader(shader); + addshaders.push(shader); } + for (shader in addshaders) + gpass.addShader(shader); minfo.meshbatch.material.addPass(gpass); } @@ -208,9 +228,12 @@ class InstanceManager { } for (shader in minfoshaders) gpass.removeShader(shader); + var addshaders = []; for (shader in refractPass.getShaders()) { - gpass.addShader(shader); + addshaders.push(shader); } + for (shader in addshaders) + gpass.addShader(shader); minfo.meshbatch.material.addPass(gpass); } diff --git a/src/Macros.hx b/src/Macros.hx index 48fd9630..7e86ca98 100644 --- a/src/Macros.hx +++ b/src/Macros.hx @@ -113,6 +113,8 @@ class MarbleWorldMacros { "astrolabecloudsadvancedshape" ].contains(dataBlockLowerCase)) shape = new shapes.Sky(dataBlockLowerCase); + else if (dataBlockLowerCase == "astrolabeshape") + shape = new shapes.Astrolabe(); else { Console.error("Unknown item: " + element.datablock); onFinish(); diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 0c4e9c00..f1b4f100 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -495,7 +495,7 @@ class MarbleWorld extends Scheduler { var startquat = this.getStartPositionAndOrientation(); - this.marble.setPosition(startquat.position.x, startquat.position.y, startquat.position.z + 3); + this.marble.setPosition(startquat.position.x, startquat.position.y, startquat.position.z + 1.5); var oldtransform = this.marble.collider.transform.clone(); oldtransform.setPosition(startquat.position); this.marble.collider.setTransform(oldtransform); @@ -856,6 +856,8 @@ class MarbleWorld extends Scheduler { var texToLoad = []; for (i in 0...dtsFile.resource.matNames.length) { var matName = obj.matNameOverride.exists(dtsFile.resource.matNames[i]) ? obj.matNameOverride.get(dtsFile.resource.matNames[i]) : dtsFile.resource.matNames[i]; + if (matName.indexOf('/') != -1) + matName = matName.substring(matName.lastIndexOf('/')); var fullNames = ResourceLoader.getFullNamesOf(directoryPath + '/' + matName).filter(x -> haxe.io.Path.extension(x) != "dts"); var fullName = fullNames.length > 0 ? fullNames[0] : null; if (fullName != null) { diff --git a/src/Renderer.hx b/src/Renderer.hx index 96e25e3d..39b525e7 100644 --- a/src/Renderer.hx +++ b/src/Renderer.hx @@ -45,7 +45,12 @@ 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") + if (name == "alpha" + || name == "additive" + || name == "glowPre" + || name == "glow" + || name == "refract" + || name == "glowPreNoRender") return defaultPass; return super.getPassByName(name); } diff --git a/src/dts/DtsFile.hx b/src/dts/DtsFile.hx index 16279695..23897d84 100644 --- a/src/dts/DtsFile.hx +++ b/src/dts/DtsFile.hx @@ -1,5 +1,6 @@ package dts; +import src.Console; import haxe.Exception; import dif.io.BytesReader; import dif.math.QuatF; @@ -600,4 +601,247 @@ class DtsFile { matReflectionAmounts.push(br.readFloat()); } } + + function readName(br:BytesReader, addName:Bool) { + var sz = br.readInt32(); + var nameIndex = -1; + if (sz > 0) { + var str = ""; + for (i in 0...sz) { + str += String.fromCharCode(br.readByte()); + } + nameIndex = names.indexOf(str); + if (nameIndex < 0 && addName) { + nameIndex = names.length; + names.push(str); + } + } + return nameIndex; + } + + public function importSequences(filepath:String) { + var f = ResourceLoader.getFileEntry(filepath).entry; + var bytes = f.getBytes(); + var br = new BytesReader(bytes); + + var version = br.readInt32(); + var sz = br.readInt32(); + var checkForDups = []; + var nodeMap = []; + for (i in 0...sz) + nodeMap.push(0); + for (i in 0...sz) { + var startSize = names.length; + var nameIndex = readName(br, true); + var count = 0; + if (nameIndex >= 0) { + while (checkForDups.length < nameIndex + 1) + checkForDups.push(0); + count = checkForDups[nameIndex]++; + } + if (count > 0) { + nodeMap[i] = -1; + var jout = 0; + for (j in 0...nodes.length) { + if (nodes[j].name == nameIndex && count-- == 0) + break; + jout++; + } + nodeMap[i] = jout; + if (jout == nodes.length) { + Console.error("Sequence import failed, a node is duplicated more in sequence than in shape."); + return false; + } + } else { + nodeMap[i] = nodes.indexOf(nodes.filter(x -> x.name == nameIndex)[0]); + } + if (nodeMap[i] < 0) { + // error -- node found in sequence but not shape + Console.error("Sequence import failed, a node is duplicated more in sequence than in shape."); + if (names.length != startSize) { + names.pop(); + } + return false; + } + } + + sz = br.readInt32(); + var oldShapeNumObjects = br.readInt32(); + + var keyframes = []; + if (version < 17) { + var sz = br.readInt32(); + for (i in 0...sz) { + keyframes.push(KeyFrame.read(br)); + } + } + + var adjNodeRots = version < 22 ? nodeRotations.length - nodeMap.length : nodeRotations.length; + var adjNodeTrans = version < 22 ? nodeTranslations.length - nodeMap.length : nodeTranslations.length; + var adjNodeScales1 = nodeUniformScales.length; + var adjNodeScales2 = nodeAlignedScales.length; + var adjNodeScales3 = nodeArbitraryScaleFactors.length; + var adjObjectStates = objectStates.length - oldShapeNumObjects; + var adjGroundStates = version < 22 ? 0 : groundTranslations.length; // groundTrans==groundRot + + for (i in 0...keyframes.length) { + // have keyframes only for old shapes...use adjNodeRots for adjustment + // since same as adjNodeScales... + keyframes[i].firstNodeState += adjNodeRots; + keyframes[i].firstObjectState += adjObjectStates; + } + + function readS16() { + var val = br.readInt16(); + if (val > 32767) + val -= 65536; + return val; + } + + // add these node states to our own + if (version > 21) { + sz = br.readInt32(); + for (i in 0...sz) { + var q = new QuatF(); + q.x = readS16(); + q.y = readS16(); + q.z = readS16(); + q.w = readS16(); + nodeRotations.push(q); + } + sz = br.readInt32(); + for (i in 0...sz) { + var p = new Point3F(); + p.x = br.readFloat(); + p.y = br.readFloat(); + p.z = br.readFloat(); + nodeTranslations.push(p); + } + sz = br.readInt32(); + for (i in 0...sz) + nodeUniformScales.push(br.readFloat()); + sz = br.readInt32(); + for (i in 0...sz) { + var p = new Point3F(); + p.x = br.readFloat(); + p.y = br.readFloat(); + p.z = br.readFloat(); + nodeAlignedScales.push(p); + } + sz = br.readInt32(); + for (i in 0...sz) { + var q = new QuatF(); + q.x = readS16(); + q.y = readS16(); + q.z = readS16(); + q.w = readS16(); + nodeArbitraryScaleRots.push(q); + } + for (i in 0...sz) { + var p = new Point3F(); + p.x = br.readFloat(); + p.y = br.readFloat(); + p.z = br.readFloat(); + nodeArbitraryScaleFactors.push(p); + } + sz = br.readInt32(); + for (i in 0...sz) { + var p = new Point3F(); + p.x = br.readFloat(); + p.y = br.readFloat(); + p.z = br.readFloat(); + groundTranslations.push(p); + } + for (i in 0...sz) { + var q = new QuatF(); + q.x = readS16(); + q.y = readS16(); + q.z = readS16(); + q.w = readS16(); + groundRots.push(q); + } + } else { + sz = br.readInt32(); + for (i in 0...sz) { + var q = new QuatF(); + q.x = readS16(); + q.y = readS16(); + q.z = readS16(); + q.w = readS16(); + var p = new Point3F(); + p.x = br.readFloat(); + p.y = br.readFloat(); + p.z = br.readFloat(); + nodeRotations.push(q); + nodeTranslations.push(p); + } + } + + sz = br.readInt32(); + sz = br.readInt32(); + var startSeqNum = sequences.length; + for (i in 0...sz) { + var seq = new Sequence(); + seq.nameIndex = readName(br, true); + seq.read(br, fileVersion, false); + + if (version > 21) { + seq.baseRotation += adjNodeRots; + seq.baseTranslation += adjNodeTrans; + if (seq.flags & 1 > 0) + seq.baseScale += adjNodeScales1; + else if (seq.flags & 2 > 0) + seq.baseScale += adjNodeScales2; + else if (seq.flags & 4 > 0) + seq.baseScale += adjNodeScales3; + } else if (version >= 17) { + seq.baseRotation += adjNodeRots; // == adjNodeTrans + seq.baseTranslation += adjNodeTrans; // == adjNodeTrans + } + + var newTM = 0; + var newRM = 0; + var newSM = 0; + for (j in 0...nodeMap.length) { + if (seq.translationMatters[0] & (1 << j) > 0) + newTM |= (1 << nodeMap[j]); + if (seq.rotationMatters[0] & (1 << j) > 0) + newRM |= (1 << nodeMap[j]); + if (seq.scaleMatters[0] & (1 << j) > 0) + newSM |= (1 << nodeMap[j]); + } + seq.translationMatters[0] = newTM; + seq.rotationMatters[0] = newRM; + seq.scaleMatters[0] = newSM; + seq.firstTrigger += triggers.length; + seq.firstGroundFrame += adjGroundStates; + + sequences.push(seq); + } + + if (version < 17) + return false; // Cannot, not actually needed in this game + + if (version < 22) { + for (i in startSeqNum...sequences.length) { + var oldSz = groundTranslations.length; + for (j in 0...sequences[i].numGroundFrames) { + groundTranslations.push(nodeTranslations[sequences[i].firstGroundFrame + adjNodeTrans + j]); + groundRots.push(nodeRotations[sequences[i].firstGroundFrame + adjNodeRots + j]); + } + sequences[i].firstGroundFrame = oldSz; + } + } + + if (version > 8) { + sz = br.readInt32(); + for (i in 0...sz) { + var t = new Trigger(); + t.state = br.readInt32(); + t.position = br.readFloat(); + } + } + + return true; + } } diff --git a/src/dts/KeyFrame.hx b/src/dts/KeyFrame.hx new file mode 100644 index 00000000..8013608c --- /dev/null +++ b/src/dts/KeyFrame.hx @@ -0,0 +1,20 @@ +package dts; + +import dif.io.BytesReader; + +@:publicFields +class KeyFrame { + var firstNodeState:Int; + var firstObjectState:Int; + var firstDecalState:Int; + + public function new() {} + + public static function read(reader:BytesReader) { + var k = new KeyFrame(); + k.firstNodeState = reader.readInt32(); + k.firstObjectState = reader.readInt32(); + k.firstDecalState = reader.readInt32(); + return k; + } +} diff --git a/src/dts/ObjectState.hx b/src/dts/ObjectState.hx index 1900bdcb..8fdd213b 100644 --- a/src/dts/ObjectState.hx +++ b/src/dts/ObjectState.hx @@ -2,6 +2,7 @@ package dts; import dif.io.BytesReader; +@:publicFields class ObjectState { var vis:Float; var frame:Int; diff --git a/src/dts/Trigger.hx b/src/dts/Trigger.hx index 538db106..5fb42486 100644 --- a/src/dts/Trigger.hx +++ b/src/dts/Trigger.hx @@ -2,6 +2,7 @@ package dts; import dif.io.BytesReader; +@:publicFields class Trigger { var state:Int; var position:Float; diff --git a/src/shapes/Astrolabe.hx b/src/shapes/Astrolabe.hx new file mode 100644 index 00000000..943b13ff --- /dev/null +++ b/src/shapes/Astrolabe.hx @@ -0,0 +1,30 @@ +package shapes; + +import src.DtsObject; + +class Astrolabe extends DtsObject { + public function new() { + super(); + this.dtsPath = "data/shapes/astrolabe/astrolabe.dts"; + this.sequencePath = "data/shapes/astrolabe/astrolabe_root.dsq"; + this.isCollideable = false; + this.isTSStatic = false; + this.identifier = "Astrolabe"; + this.useInstancing = false; + } + + public override function init(level:src.MarbleWorld, onFinish:() -> Void) { + super.init(level, onFinish); + for (mat in this.materials) { + var thisprops:Dynamic = mat.getDefaultProps(); + thisprops.light = false; // We will calculate our own lighting + mat.props = thisprops; + mat.shadows = false; + mat.receiveShadows = false; + mat.blendMode = Alpha; + mat.mainPass.depthWrite = false; + mat.mainPass.culling = h3d.mat.Data.Face.None; + mat.mainPass.setPassName("skyshape"); + } + } +} diff --git a/src/shapes/Checkpoint.hx b/src/shapes/Checkpoint.hx index e5272d18..e0782168 100644 --- a/src/shapes/Checkpoint.hx +++ b/src/shapes/Checkpoint.hx @@ -18,6 +18,7 @@ class Checkpoint extends DtsObject { this.isTSStatic = false; this.identifier = "Checkpoint"; this.element = element; + this.animateSubObjectOpacities = true; this.disableOOB = element.fields.exists('disableOob') ? MisParser.parseBoolean(element.fields['disableOob'][0]) : false; } @@ -34,4 +35,52 @@ class Checkpoint extends DtsObject { elem: this.element }, null); } + + override function postProcessMaterial(matName:String, material:h3d.mat.Material) { + if (matName == "sigil") { + var diffuseTex = ResourceLoader.getTexture("data/shapes/pads/sigil.png").resource; + diffuseTex.wrap = Repeat; + diffuseTex.mipMap = Nearest; + + var trivialShader = new shaders.TrivialMaterial(diffuseTex); + + var glowpass = material.mainPass.clone(); + glowpass.addShader(trivialShader); + var dtsshader = glowpass.getShader(shaders.DtsTexture); + dtsshader.passThrough = true; + glowpass.setPassName("glow"); + glowpass.depthTest = LessEqual; + glowpass.enableLights = false; + glowpass.setBlendMode(Alpha); + material.addPass(glowpass); + + material.mainPass.setPassName("glowPre"); + material.mainPass.addShader(trivialShader); + dtsshader = material.mainPass.getShader(shaders.DtsTexture); + if (dtsshader != null) + material.mainPass.removeShader(dtsshader); + material.mainPass.enableLights = false; + material.mainPass.setBlendMode(Alpha); + } + if (matName == "sigiloff") { + var diffuseTex = ResourceLoader.getTexture("data/shapes/pads/sigiloff.png").resource; + diffuseTex.wrap = Repeat; + diffuseTex.mipMap = Nearest; + var shader = new shaders.DefaultDiffuseMaterial(diffuseTex); + var dtsTex = material.mainPass.getShader(shaders.DtsTexture); + dtsTex.passThrough = true; + material.mainPass.removeShader(material.textureShader); + material.mainPass.addShader(shader); + var thisprops:Dynamic = material.getDefaultProps(); + thisprops.light = false; // We will calculate our own lighting + material.props = thisprops; + material.shadows = false; + material.receiveShadows = true; + material.blendMode = Alpha; + } + if (matName == "corona") { + material.blendMode = Alpha; + material.mainPass.enableLights = false; + } + } } diff --git a/src/shapes/RoundBumper.hx b/src/shapes/RoundBumper.hx index 13fd4079..42d20633 100644 --- a/src/shapes/RoundBumper.hx +++ b/src/shapes/RoundBumper.hx @@ -13,6 +13,7 @@ class RoundBumper extends AbstractBumper { dtsPath = "data/shapes/bumpers/pball_round.dts"; isCollideable = true; identifier = "RoundBumper"; + animateSubObjectOpacities = true; } override function postProcessMaterial(matName:String, material:h3d.mat.Material) { @@ -42,8 +43,8 @@ class RoundBumper extends AbstractBumper { var glowpass = material.mainPass.clone(); glowpass.addShader(trivialShader); var dtsshader = glowpass.getShader(shaders.DtsTexture); - if (dtsshader != null) - glowpass.removeShader(dtsshader); + dtsshader.passThrough = true; + glowpass.setPassName("glow"); glowpass.depthTest = LessEqual; glowpass.enableLights = false; @@ -73,18 +74,12 @@ class RoundBumper extends AbstractBumper { glowpass.addShader(trivialShader); var dtsshader = glowpass.getShader(shaders.DtsTexture); - if (dtsshader != null) - glowpass.removeShader(dtsshader); + dtsshader.passThrough = true; glowpass.setPassName("glow"); glowpass.depthTest = LessEqual; glowpass.depthWrite = false; glowpass.enableLights = false; - glowpass.blendSrc = SrcAlpha; - glowpass.blendDst = One; - glowpass.blendOp = Add; - glowpass.blendAlphaSrc = SrcAlpha; - glowpass.blendAlphaDst = One; - glowpass.blendAlphaOp = Add; + glowpass.setBlendMode(Alpha); // glowpass.blendSrc = SrcAlpha; // glowpass.blendDst = OneMinusSrcAlpha; material.addPass(glowpass); @@ -93,8 +88,7 @@ class RoundBumper extends AbstractBumper { material.mainPass.removeShader(material.textureShader); material.mainPass.addShader(trivialShader); dtsshader = material.mainPass.getShader(shaders.DtsTexture); - if (dtsshader != null) - material.mainPass.removeShader(dtsshader); + dtsshader.passThrough = true; material.mainPass.enableLights = false; // var thisprops:Dynamic = material.getDefaultProps(); diff --git a/src/shapes/Sky.hx b/src/shapes/Sky.hx index 968b7b5f..4e41471c 100644 --- a/src/shapes/Sky.hx +++ b/src/shapes/Sky.hx @@ -28,6 +28,7 @@ class Sky extends DtsObject { mat.shadows = false; mat.receiveShadows = false; mat.blendMode = Alpha; + mat.mainPass.depthWrite = false; mat.mainPass.culling = h3d.mat.Data.Face.None; mat.mainPass.setPassName("skyshape"); } diff --git a/src/shapes/StartPad.hx b/src/shapes/StartPad.hx index a3e699b7..bcde7a98 100644 --- a/src/shapes/StartPad.hx +++ b/src/shapes/StartPad.hx @@ -12,6 +12,14 @@ class StartPad extends DtsObject { isCollideable = true; identifier = "StartPad"; useInstancing = false; + animateSubObjectOpacities = true; + doSequenceOnce = true; + doSequenceOnceBeginTime = 0; + } + + override function reset() { + super.reset(); + doSequenceOnceBeginTime = level.timeState.timeSinceLoad; } override function postProcessMaterial(matName:String, material:h3d.mat.Material) {