Add a lot of static shapes, fix some collision stuff

This commit is contained in:
RandomityGuy 2021-06-10 17:12:39 +05:30
parent f08fb95648
commit b20d084b46
23 changed files with 224 additions and 40 deletions

View file

@ -202,8 +202,7 @@ class DtsObject extends GameObject {
if (this.isCollideable) {
for (i in 0...dts.nodes.length) {
var objects = dts.objects.filter(object -> object.node == i);
var meshSurfaces = [];
var collider = new CollisionHull(cast this);
var localColliders:Array<CollisionEntity> = [];
for (object in objects) {
var isCollisionObject = dts.names[object.name].substr(0, 3).toLowerCase() == "col";
@ -220,17 +219,12 @@ class DtsObject extends GameObject {
var vertices = mesh.vertices.map(v -> new Vector(v.x, v.y, v.z));
var vertexNormals = mesh.normals.map(v -> new Vector(v.x, v.y, v.z));
var surfaces = this.generateCollisionGeometry(mesh, vertices, vertexNormals);
for (surface in surfaces)
collider.addSurface(surface);
meshSurfaces = meshSurfaces.concat(surfaces);
var hulls = this.generateCollisionGeometry(mesh, vertices, vertexNormals, i);
localColliders = localColliders.concat(hulls);
}
}
}
if (meshSurfaces.length != 0)
colliders.push(collider);
else
colliders.push(null);
colliders = colliders.concat(localColliders);
}
}
@ -424,22 +418,24 @@ class DtsObject extends GameObject {
}
}
function generateCollisionGeometry(dtsMesh:dts.Mesh, vertices:Array<Vector>, vertexNormals:Array<Vector>) {
var surfaces = this.dts.matNames.map(x -> new CollisionSurface());
for (surface in surfaces) {
surface.points = [];
surface.normals = [];
surface.indices = [];
}
function generateCollisionGeometry(dtsMesh:dts.Mesh, vertices:Array<Vector>, vertexNormals:Array<Vector>, node:Int) {
var hulls:Array<CollisionEntity> = [];
for (primitive in dtsMesh.primitives) {
var k = 0;
var geometrydata = surfaces[primitive.matIndex];
var chull = new CollisionHull(cast this);
chull.userData = node;
var hs = new CollisionSurface();
hs.points = [];
hs.normals = [];
hs.indices = [];
var material = this.dts.matNames[primitive.matIndex];
if (dtsMaterials.exists(material)) {
var data = dtsMaterials.get(material);
geometrydata.friction = data.friction;
geometrydata.force = data.force;
geometrydata.restitution = data.restitution;
hs.friction = data.friction;
hs.force = data.force;
hs.restitution = data.restitution;
}
for (i in primitive.firstElement...(primitive.firstElement + primitive.numElements - 2)) {
@ -456,24 +452,25 @@ class DtsObject extends GameObject {
for (index in [i1, i2, i3]) {
var vertex = vertices[index];
geometrydata.points.push(new Vector(vertex.x, vertex.y, vertex.z));
hs.points.push(new Vector(vertex.x, vertex.y, vertex.z));
var normal = vertexNormals[index];
geometrydata.normals.push(new Vector(normal.x, normal.y, normal.z));
hs.normals.push(new Vector(normal.x, normal.y, normal.z));
}
geometrydata.indices.push(geometrydata.indices.length);
geometrydata.indices.push(geometrydata.indices.length);
geometrydata.indices.push(geometrydata.indices.length);
hs.indices.push(hs.indices.length);
hs.indices.push(hs.indices.length);
hs.indices.push(hs.indices.length);
k++;
}
hs.generateBoundingBox();
chull.addSurface(hs);
chull.generateBoundingBox();
hulls.push(chull);
}
for (surface in surfaces) {
surface.generateBoundingBox();
// surface.generateNormals();
}
return surfaces;
return hulls;
}
function generateMaterialGeometry(dtsMesh:dts.Mesh, vertices:Array<Vector>, vertexNormals:Array<Vector>) {
@ -773,7 +770,7 @@ class DtsObject extends GameObject {
}
for (i in 0...this.colliders.length) {
var absTform = this.graphNodes[i].getAbsPos().clone();
var absTform = this.graphNodes[this.colliders[i].userData].getAbsPos().clone();
if (this.colliders[i] != null)
this.colliders[i].setTransform(absTform);
}

View file

@ -1,5 +1,9 @@
package;
import shapes.StartPad;
import shapes.TriangleBumper;
import shapes.RoundBumper;
import shapes.Oilslick;
import gui.PlayGui;
import shapes.Helicopter;
import shapes.ShockAbsorber;
@ -117,6 +121,31 @@ class Main extends hxd.App {
ag.y = 6;
world.addDtsObject(ag);
var os = new Oilslick();
os.x = 5;
os.z = 0.1;
world.addDtsObject(os);
var tdoor = new Trapdoor();
tdoor.x = -5;
tdoor.z = 1;
world.addDtsObject(tdoor);
var rb = new RoundBumper();
rb.x = -5;
rb.y = 2;
world.addDtsObject(rb);
var tb = new TriangleBumper();
tb.x = -5;
tb.y = 4;
world.addDtsObject(tb);
var spad = new StartPad();
tb.x = 5;
tb.y = 3;
world.addDtsObject(spad);
// var le:ParticleEmitterOptions = {
// ejectionPeriod: 0.01,

View file

@ -235,11 +235,14 @@ class Marble extends GameObject {
var contactNormal = new Vector();
var forceObjectCount = 0;
var forceObjects = [];
for (contact in contacts) {
if (contact.force != 0) {
if (contact.force != 0 && !forceObjects.contains(contact.otherObject)) {
forceObjectCount++;
contactNormal = contactNormal.add(contact.normal);
contactForce += contact.force;
forceObjects.push(contact.otherObject);
}
}

View file

@ -47,6 +47,9 @@ class MarbleWorld extends Scheduler {
public var currentUp = new Vector(0, 0, 1);
public var outOfBounds:Bool = false;
var helpTextTimeState:Float = -1e8;
var alertTextTimeState:Float = -1e8;
var orientationChangeTime = -1e8;
var oldOrientationQuat = new Quat();
@ -182,6 +185,7 @@ class MarbleWorld extends Scheduler {
if (this.marble != null) {
callCollisionHandlers(marble);
}
this.updateTexts();
}
public function render(e:h3d.Engine) {
@ -202,6 +206,20 @@ class MarbleWorld extends Scheduler {
playGui.formatTimer(this.elapsedTime);
}
function updateTexts() {
var helpTextTime = this.helpTextTimeState;
var alertTextTime = this.alertTextTimeState;
var helpTextCompletion = Math.pow(Util.clamp((this.currentTime - helpTextTime - 3), 0, 1), 2);
var alertTextCompletion = Math.pow(Util.clamp((this.currentTime - alertTextTime - 3), 0, 1), 2);
this.playGui.setHelpTextOpacity(1 - helpTextCompletion);
this.playGui.setAlertTextOpacity(1 - alertTextCompletion);
}
public function displayAlert(text:String) {
this.playGui.setAlertText(text);
this.alertTextTimeState = this.currentTime;
}
function callCollisionHandlers(marble:Marble) {
var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius);
var newImmunity = [];

View file

@ -74,7 +74,7 @@ class ResourceLoader {
public static function getFullNamesOf(path:String) {
var files = fileSystem.dir(Path.directory(path)); // FileSystem.readDirectory(Path.directory(path));
var names = [];
var fname = Path.withoutExtension(Path.withoutDirectory(path)).toLowerCase();
var fname = Path.withoutDirectory(path).toLowerCase();
for (file in files) {
var fname2 = file.name;
if (Path.withoutExtension(fname2).toLowerCase() == fname)

View file

@ -25,6 +25,8 @@ class CollisionEntity implements IOctreeObject {
public var transform:Matrix;
public var go:GameObject;
public var userData:Int;
public function new(go:GameObject) {
this.go = go;
this.octree = new Octree();
@ -128,6 +130,7 @@ class CollisionEntity implements IOctreeObject {
// cinfo.collider = this;
cinfo.velocity = this.velocity;
cinfo.contactDistance = closest.distance(position);
cinfo.otherObject = this.go;
// cinfo.penetration = radius - (position.sub(closest).dot(normal));
cinfo.restitution = surface.restitution;
cinfo.force = surface.force;

View file

@ -44,6 +44,7 @@ class CollisionHull extends CollisionEntity {
cinfo.velocity = velocity;
cinfo.contactDistance = sph.radius + pt.length();
cinfo.restitution = restitution;
cinfo.otherObject = this.go;
cinfo.friction = friction;
cinfo.force = force;
this.go.onMarbleContact(dt, cinfo);

View file

@ -1,5 +1,6 @@
package collision;
import src.GameObject;
import h3d.Vector;
class CollisionInfo {
@ -7,6 +8,7 @@ class CollisionInfo {
public var normal:Vector;
public var velocity:Vector;
public var collider:CollisionEntity;
public var otherObject:GameObject;
public var friction:Float;
public var vAtCMag:Float;
public var normalForce:Float;

View file

@ -48,6 +48,7 @@ class SphereCollisionEntity extends CollisionEntity {
contact.friction = 1;
contact.restitution = 1;
contact.velocity = this.velocity;
contact.otherObject = this.go;
contact.point = position.add(normDist);
contact.normal = normDist.multiply(-1);
contact.force = 0;

View file

@ -151,7 +151,7 @@ class PlayGui {
gemImageObject.dtsPath = "data/shapes/items/gem.dts";
gemImageObject.ambientRotate = true;
gemImageObject.showSequences = false;
gemImageObject.matNameOverride.set("base.gem", "base.gem.png");
// gemImageObject.matNameOverride.set("base.gem", "base.gem.");
gemImageObject.ambientSpinFactor /= -2;
// ["base.gem"] = color + ".gem";
gemImageObject.init(null);
@ -186,30 +186,49 @@ class PlayGui {
var bfont = new BitmapFont(fontdata.entry);
@:privateAccess bfont.loader = ResourceLoader.loader;
helpTextBackground = new Text(bfont.toFont(), scene2d);
helpTextBackground.text = "Hello Bruh";
helpTextBackground.text = "Bruh";
helpTextBackground.x = scene2d.width / 2 - helpTextBackground.textWidth / 2 + 1;
helpTextBackground.y = scene2d.height * 0.45 + 1;
helpTextBackground.textColor = 0x000000;
helpTextForeground = new Text(bfont.toFont(), scene2d);
helpTextForeground.text = "Hello Bruh";
helpTextForeground.text = "Bruh";
helpTextForeground.x = scene2d.width / 2 - helpTextForeground.textWidth / 2;
helpTextForeground.y = scene2d.height * 0.45;
helpTextForeground.textColor = 0xFFFFFF;
alertTextBackground = new Text(bfont.toFont(), scene2d);
alertTextBackground.text = "Hello Bruh";
alertTextBackground.text = "Bruh";
alertTextBackground.x = scene2d.width / 2 - alertTextBackground.textWidth / 2 + 1;
alertTextBackground.y = scene2d.height - 102 + 1;
alertTextBackground.textColor = 0x000000;
alertTextForeground = new Text(bfont.toFont(), scene2d);
alertTextForeground.text = "Hello Bruh";
alertTextForeground.text = "Bruh";
alertTextForeground.x = scene2d.width / 2 - alertTextForeground.textWidth / 2;
alertTextForeground.y = scene2d.height - 102;
alertTextForeground.textColor = 0xFFE240;
}
public function setHelpTextOpacity(value:Float) {
helpTextForeground.color.a = value;
helpTextBackground.color.a = value;
}
public function setAlertTextOpacity(value:Float) {
alertTextForeground.color.a = value;
alertTextBackground.color.a = value;
}
public function setAlertText(text:String) {
this.alertTextForeground.text = text;
this.alertTextBackground.text = text;
alertTextForeground.x = scene2d.width / 2 - alertTextForeground.textWidth / 2;
alertTextForeground.y = scene2d.height - 102;
alertTextBackground.x = scene2d.width / 2 - alertTextBackground.textWidth / 2 + 1;
alertTextBackground.y = scene2d.height - 102 + 1;
}
public function setPowerupImage(powerupIdentifier:String) {
this.powerupImageScene.removeChildren();
if (powerupIdentifier == "SuperJump") {

View file

@ -10,6 +10,7 @@ class AntiGravity extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "AntiGravity";
this.pickUpName = "Gravity Modifier";
this.autoUse = true;
}

View file

@ -10,6 +10,7 @@ class Helicopter extends PowerUp {
this.isTSStatic = false;
this.showSequences = false;
this.identifier = "Helicopter";
this.pickUpName = "Gyrocopter PowerUp";
}
public function pickUp():Bool {

14
src/shapes/Oilslick.hx Normal file
View file

@ -0,0 +1,14 @@
package shapes;
import src.DtsObject;
class Oilslick extends DtsObject {
public function new() {
super();
this.dtsPath = "data/shapes/hazards/oilslick.dts";
this.identifier = "Oilslick";
this.useInstancing = true;
this.isCollideable = true;
this.isTSStatic = false;
}
}

View file

@ -27,6 +27,7 @@ abstract class PowerUp extends DtsObject {
public var cooldownDuration:Float = 7;
public var autoUse:Bool = false;
public var powerupParams:PowerupParams = new PowerupParams();
public var pickUpName:String;
public function new() {
super();
@ -46,7 +47,7 @@ abstract class PowerUp extends DtsObject {
if (this.autoUse)
this.use(time);
// displayAlert(`You picked up a ${this.pickUpName}!`);
this.level.displayAlert('You picked up a ${this.pickUpName}!');
// if (this.element.showhelponpickup === "1" && !this.autoUse) displayHelp(`Press <func:bind mousefire> to use the ${this.pickUpName}!`);
}
}

12
src/shapes/RoundBumper.hx Normal file
View file

@ -0,0 +1,12 @@
package shapes;
import src.DtsObject;
class RoundBumper extends DtsObject {
public function new() {
super();
dtsPath = "data/shapes/bumpers/pball_round.dts";
isCollideable = true;
identifier = "RoundBumper";
}
}

View file

@ -9,6 +9,7 @@ class ShockAbsorber extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "ShockAbsorber";
this.pickUpName = "Shock Absorber PowerUp";
}
public function pickUp():Bool {

13
src/shapes/StartPad.hx Normal file
View file

@ -0,0 +1,13 @@
package shapes;
import src.DtsObject;
class StartPad extends DtsObject {
public function new() {
super();
dtsPath = "data/shapes/pads/startarea.dts";
useInstancing = false;
isCollideable = true;
identifier = "StartPad";
}
}

View file

@ -9,6 +9,7 @@ class SuperBounce extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "SuperBounce";
this.pickUpName = "Super Bounce PowerUp";
}
public function pickUp():Bool {

View file

@ -37,6 +37,7 @@ class SuperJump extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "SuperJump";
this.pickUpName = "Super Jump PowerUp";
sjEmitterParticleData = new ParticleData();
sjEmitterParticleData.identifier = "superJumpParticle";
sjEmitterParticleData.texture = ResourceLoader.getTexture("data/particles/twirl.png");

View file

@ -43,6 +43,7 @@ class SuperSpeed extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "SuperSpeed";
this.pickUpName = "Super Speed PowerUp";
this.useInstancing = true;
ssEmitterParticleData = new ParticleData();
ssEmitterParticleData.identifier = "superSpeedParticle";

View file

@ -7,6 +7,7 @@ class TimeTravel extends PowerUp {
this.isCollideable = false;
this.isTSStatic = false;
this.identifier = "TimeTravel";
this.pickUpName = '${this.timeBonus} second Time Travel bonus';
this.cooldownDuration = 1e8;
this.useInstancing = true;
this.autoUse = true;

View file

@ -1,15 +1,67 @@
package shapes;
import collision.CollisionInfo;
import src.Util;
import src.DtsObject;
import h3d.Vector;
import src.ForceObject;
class Trapdoor extends DtsObject {
var lastContactTime = -1e8;
var timeout:Float = 0;
var lastDirection:Float;
var lastCompletion:Float = 0;
public function new() {
super();
this.dtsPath = "data/shapes/hazards/trapdoor.dts";
this.isCollideable = true;
this.isTSStatic = false;
this.identifier = "Trapdoor";
this.hasNonVisualSequences = true;
}
public override function update(currentTime:Float, dt:Float) {
var currentCompletion = this.getCurrentCompletion(currentTime);
// Override the keyframe
this.sequenceKeyframeOverride.set(this.dts.sequences[0], currentCompletion * (this.dts.sequences[0].numKeyFrames - 1));
super.update(currentTime, dt);
var diff = (currentCompletion - this.lastCompletion);
var direction = 0;
if (diff > 0)
direction = 1;
if (diff < 0)
direction = -1;
if (direction != 0 && direction != this.lastDirection) {
// If the direction has changed, play the sound
// AudioManager.play(this.sounds[0], 1, AudioManager.soundGain, this.worldPosition);
}
this.lastCompletion = currentCompletion;
this.lastDirection = direction;
}
function getCurrentCompletion(time:Float) {
var elapsed = time - this.lastContactTime;
var completion = Util.clamp(elapsed / 1.6666676998138428, 0, 1);
if (elapsed > 5)
completion = Util.clamp(1 - (elapsed - 5) / 1.6666676998138428, 0, 1);
return completion;
}
override function onMarbleContact(time:Float, ?contact:CollisionInfo) {
super.onMarbleContact(this.level.currentTime, contact);
if (this.level.currentTime - this.lastContactTime <= 0)
return; // The trapdoor is queued to open, so don't do anything.
var currentCompletion = this.getCurrentCompletion(this.level.currentTime);
// Set the last contact time accordingly so that the trapdoor starts closing (again)
this.lastContactTime = this.level.currentTime - currentCompletion * 1.6666676998138428;
if (currentCompletion == 0)
this.lastContactTime += this.timeout;
// this.level.replay.recordMarbleContact(this);
}
}

View file

@ -0,0 +1,12 @@
package shapes;
import src.DtsObject;
class TriangleBumper extends DtsObject {
public function new() {
super();
dtsPath = "data/shapes/bumpers/pball_tri.dts";
identifier = "TriangleBumper";
isCollideable = true;
}
}