From f69a899c8aaca8f39c0ab7a013308be8e2d3840f Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:47:18 +0530 Subject: [PATCH] Add bounds collision handlers --- src/DifBuilder.hx | 2 +- src/DtsObject.hx | 11 ++++- src/GameObject.hx | 9 ++++ src/Marble.hx | 3 +- src/MarbleWorld.hx | 57 ++++++++++++++++++++++++++ src/collision/BoxCollisionEntity.hx | 33 +++++++++++++++ src/collision/CollisionEntity.hx | 5 ++- src/collision/CollisionHull.hx | 6 ++- src/collision/SphereCollisionEntity.hx | 2 +- 9 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/collision/BoxCollisionEntity.hx diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index 43827552..36eaaa40 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -81,7 +81,7 @@ class DifBuilder { var triangles = []; var textures = []; - var collider = new CollisionEntity(); + var collider = new CollisionEntity(itr); function stripTexName(tex:String) { var dotpos = tex.lastIndexOf("."); diff --git a/src/DtsObject.hx b/src/DtsObject.hx index b27bb59f..4712632c 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -1,5 +1,6 @@ package src; +import collision.BoxCollisionEntity; import shaders.DtsTexture; import h3d.shader.AlphaMult; import sys.io.File; @@ -94,6 +95,7 @@ class DtsObject extends GameObject { var rootObject:Object; var colliders:Array; + var boundingCollider:BoxCollisionEntity; var mountPointNodes:Array; var alphaShader:AlphaMult; @@ -197,7 +199,7 @@ class DtsObject extends GameObject { for (i in 0...dts.nodes.length) { var objects = dts.objects.filter(object -> object.node == i); var meshSurfaces = []; - var collider = new CollisionHull(); + var collider = new CollisionHull(cast this); for (object in objects) { var isCollisionObject = dts.names[object.name].substr(0, 3).toLowerCase() == "col"; @@ -297,6 +299,8 @@ class DtsObject extends GameObject { } rootObject.scaleX = -1; + + this.boundingCollider = new BoxCollisionEntity(this.getBounds().clone(), cast this); } function computeMaterials() { @@ -533,6 +537,11 @@ class DtsObject extends GameObject { return geo; } + public override function setTransform(mat:Matrix) { + super.setTransform(mat); + this.boundingCollider.setTransform(mat); + } + public function update(currentTime:Float, dt:Float) { for (sequence in this.dts.sequences) { if (!this.showSequences) diff --git a/src/GameObject.hx b/src/GameObject.hx index 205d20f2..182ef9e5 100644 --- a/src/GameObject.hx +++ b/src/GameObject.hx @@ -1,8 +1,17 @@ package src; +import collision.CollisionInfo; import h3d.scene.Object; class GameObject extends Object { public var identifier:String; public var currentOpacity:Float = 1; + + public function onMarbleContact(time:Float, ?contact:CollisionInfo) {} + + public function onMarbleInside(time:Float) {} + + public function onMarbleEnter(time:Float) {} + + public function onMarbleLeave(time:Float) {} } diff --git a/src/Marble.hx b/src/Marble.hx index 1a454f12..2db337f4 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1,5 +1,6 @@ package src; +import src.GameObject; import src.ForceObject; import src.MarbleWorld; import h3d.Quat; @@ -31,7 +32,7 @@ class Move { public function new() {} } -class Marble extends Object { +class Marble extends GameObject { public var camera:CameraController; public var cameraObject:Object; public var controllable:Bool = false; diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index 2a7bb3b8..71a4debc 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1,5 +1,6 @@ package src; +import collision.SphereCollisionEntity; import src.Sky; import h3d.scene.Mesh; import src.InstanceManager; @@ -23,11 +24,16 @@ class MarbleWorld { public var marbles:Array = []; public var dtsObjects:Array = []; + var shapeImmunity:Array = []; + var shapeOrTriggerInside:Array = []; + public var currentTime:Float = 0; public var sky:Sky; public var scene:Scene; + var marble:Marble; + public function new(scene:Scene) { this.collisionWorld = new CollisionWorld(); this.scene = scene; @@ -69,6 +75,7 @@ class MarbleWorld { if (collider != null) this.collisionWorld.addEntity(collider); } + this.collisionWorld.addEntity(obj.boundingCollider); } public function addMarble(marble:Marble) { @@ -77,6 +84,7 @@ class MarbleWorld { if (marble.controllable) { marble.camera.init(cast this); this.scene.addChild(marble.camera); + this.marble = marble; // Ugly hack sky.follow = marble; } @@ -93,5 +101,54 @@ class MarbleWorld { } this.instanceManager.update(dt); currentTime += dt; + if (this.marble != null) { + callCollisionHandlers(marble); + } + } + + function callCollisionHandlers(marble:Marble) { + var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius); + var newImmunity = []; + var calledShapes = []; + var inside = []; + + var contactsphere = new SphereCollisionEntity(marble); + contactsphere.velocity = new Vector(); + + for (contact in contacts) { + if (contact.go != marble) { + if (contact.go is DtsObject) { + var shape:DtsObject = cast contact.go; + + var contacttest = shape.colliders.map(x -> x.sphereIntersection(contactsphere, 0)); + var contactlist:Array = []; + for (l in contacttest) { + contactlist = contactlist.concat(l); + } + + if (!calledShapes.contains(shape) && !this.shapeImmunity.contains(shape) && contactlist.length != 0) { + calledShapes.push(shape); + newImmunity.push(shape); + shape.onMarbleContact(currentTime); + } + + shape.onMarbleInside(currentTime); + if (!this.shapeOrTriggerInside.contains(shape)) { + this.shapeOrTriggerInside.push(shape); + shape.onMarbleEnter(currentTime); + } + inside.push(shape); + } + } + } + + for (object in shapeOrTriggerInside) { + if (!inside.contains(object)) { + this.shapeOrTriggerInside.remove(object); + object.onMarbleLeave(currentTime); + } + } + + this.shapeImmunity = newImmunity; } } diff --git a/src/collision/BoxCollisionEntity.hx b/src/collision/BoxCollisionEntity.hx new file mode 100644 index 00000000..9578af84 --- /dev/null +++ b/src/collision/BoxCollisionEntity.hx @@ -0,0 +1,33 @@ +package collision; + +import h3d.Matrix; +import src.GameObject; +import src.Marble; +import h3d.col.Ray; +import h3d.Vector; +import h3d.col.Sphere; +import h3d.col.Bounds; + +class BoxCollisionEntity extends CollisionEntity { + var bounds:Bounds; + + public function new(bounds:Bounds, go:GameObject) { + super(go); + this.bounds = bounds; + this.generateBoundingBox(); + } + + public override function generateBoundingBox() { + this.boundingBox = bounds.clone(); + this.boundingBox.transform(this.transform); + } + + public override function isIntersectedByRay(rayOrigin:Vector, rayDirection:Vector, intersectionPoint:Vector):Bool { + // TEMP cause bruh + return boundingBox.rayIntersection(Ray.fromValues(rayOrigin.x, rayOrigin.y, rayOrigin.z, rayDirection.x, rayDirection.y, rayDirection.z), true) != -1; + } + + public override function sphereIntersection(collisionEntity:SphereCollisionEntity, dt:Float) { + return []; + } +} diff --git a/src/collision/CollisionEntity.hx b/src/collision/CollisionEntity.hx index e6c8e0a7..42ad417d 100644 --- a/src/collision/CollisionEntity.hx +++ b/src/collision/CollisionEntity.hx @@ -1,5 +1,6 @@ package collision; +import src.GameObject; import dif.math.Point3F; import dif.math.PlaneF; import h3d.col.Plane; @@ -22,8 +23,10 @@ class CollisionEntity implements IOctreeObject { public var velocity:Vector = new Vector(); public var transform:Matrix; + public var go:GameObject; - public function new() { + public function new(go:GameObject) { + this.go = go; this.octree = new Octree(); this.surfaces = []; this.transform = Matrix.I(); diff --git a/src/collision/CollisionHull.hx b/src/collision/CollisionHull.hx index ab3b927e..9ab9686c 100644 --- a/src/collision/CollisionHull.hx +++ b/src/collision/CollisionHull.hx @@ -1,5 +1,6 @@ package collision; +import src.GameObject; import h3d.col.Bounds; import collision.gjk.GJK; import collision.gjk.ConvexHull; @@ -11,8 +12,8 @@ class CollisionHull extends CollisionEntity { var restitution = 1.0; var force = 0.0; - public function new() { - super(); + public function new(go:GameObject) { + super(go); } public override function sphereIntersection(collisionEntity:SphereCollisionEntity, dt:Float):Array { @@ -45,6 +46,7 @@ class CollisionHull extends CollisionEntity { cinfo.restitution = restitution; cinfo.friction = friction; cinfo.force = force; + this.go.onMarbleContact(dt, cinfo); return [cinfo]; } } diff --git a/src/collision/SphereCollisionEntity.hx b/src/collision/SphereCollisionEntity.hx index bcfef332..811b8cae 100644 --- a/src/collision/SphereCollisionEntity.hx +++ b/src/collision/SphereCollisionEntity.hx @@ -11,7 +11,7 @@ class SphereCollisionEntity extends CollisionEntity { public var marble:Marble; public function new(marble:Marble) { - super(); + super(cast marble); this.marble = marble; this.velocity = marble.velocity; this.radius = marble._radius;