Add interior instancing and animated textures

This commit is contained in:
RandomityGuy 2021-06-04 21:50:34 +05:30
parent 4eb5a1fd27
commit 0f3be7d51b
9 changed files with 119 additions and 19 deletions

View file

@ -1,5 +1,6 @@
package src; package src;
import sys.io.File;
import src.MarbleWorld; import src.MarbleWorld;
import src.GameObject; import src.GameObject;
import collision.CollisionHull; import collision.CollisionHull;
@ -70,6 +71,7 @@ class DtsObject extends GameObject {
var level:MarbleWorld; var level:MarbleWorld;
var materials:Array<Material> = []; var materials:Array<Material> = [];
var materialInfos:Map<Material, Array<String>> = new Map();
var matNameOverride:Map<String, String> = new Map(); var matNameOverride:Map<String, String> = new Map();
var sequenceKeyframeOverride:Map<Sequence, Float> = new Map(); var sequenceKeyframeOverride:Map<Sequence, Float> = new Map();
@ -312,9 +314,11 @@ class DtsObject extends GameObject {
// TODO USE PBR??? // TODO USE PBR???
} }
} else if (Path.extension(fullName) == "ifl") { } else if (Path.extension(fullName) == "ifl") {
var keyframes = parseIfl(fullName);
this.materialInfos.set(material, keyframes);
// TODO IFL SHIT // TODO IFL SHIT
} else { } else {
var texture:Texture = ResourceLoader.loader.load(fullName).toImage().toTexture(); var texture:Texture = ResourceLoader.getTexture(fullName);
texture.wrap = Wrap.Repeat; texture.wrap = Wrap.Repeat;
material.texture = texture; material.texture = texture;
// TODO TRANSLUENCY SHIT // TODO TRANSLUENCY SHIT
@ -344,6 +348,27 @@ class DtsObject extends GameObject {
} }
} }
function parseIfl(path:String) {
var text = File.getContent(path);
var lines = text.split('\n');
var keyframes = [];
for (line in lines) {
if (line.substr(0, 2) == "//")
continue;
if (line == "")
continue;
var parts = line.split(' ');
var count = parts.length > 1 ? Std.parseInt(parts[1]) : 1;
for (i in 0...count) {
keyframes.push(parts[0]);
}
}
return keyframes;
}
function updateNodeTransforms(quaternions:Array<Quat> = null, translations:Array<Vector> = null, bitField = 0xffffffff) { function updateNodeTransforms(quaternions:Array<Quat> = null, translations:Array<Vector> = null, bitField = 0xffffffff) {
for (i in 0...this.graphNodes.length) { for (i in 0...this.graphNodes.length) {
var translation = this.dts.defaultTranslations[i]; var translation = this.dts.defaultTranslations[i];
@ -671,6 +696,29 @@ class DtsObject extends GameObject {
} }
} }
if (!this.isInstanced) {
for (i in 0...this.materials.length) {
var info = this.materialInfos.get(this.materials[i]);
if (info == null)
continue;
var iflSequence = this.dts.sequences.filter(seq -> seq.iflMatters.length > 0 ? seq.iflMatters[0] > 0 : false);
if (iflSequence.length == 0 || !this.showSequences)
continue;
var completion = (currentTime + dt) / (iflSequence[0].duration);
var keyframe = Math.floor(completion * info.length) % info.length;
var currentFile = info[keyframe];
var texture = ResourceLoader.getTexture(this.directoryPath + '/' + currentFile);
var flags = this.dts.matFlags[i];
if (flags & 1 > 0 || flags & 2 > 0)
texture.wrap = Wrap.Repeat;
this.materials[i].texture = texture;
}
}
for (i in 0...this.colliders.length) { for (i in 0...this.colliders.length) {
var absTform = this.graphNodes[i].getAbsPos().clone(); var absTform = this.graphNodes[i].getAbsPos().clone();
if (this.colliders[i] != null) if (this.colliders[i] != null)

View file

@ -61,7 +61,7 @@ class InstanceManager {
var isMesh = obj is Mesh; var isMesh = obj is Mesh;
var minfo:MeshBatchInfo = { var minfo:MeshBatchInfo = {
instances: [obj], instances: [obj],
meshbatch: isMesh ? new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material, scene) : null, meshbatch: isMesh ? new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene) : null,
mesh: isMesh ? cast obj : null mesh: isMesh ? cast obj : null
} }
minfos.push(minfo); minfos.push(minfo);

View file

@ -1,5 +1,7 @@
package src; package src;
import src.MarbleWorld;
import src.DifBuilder;
import h3d.Matrix; import h3d.Matrix;
import collision.CollisionEntity; import collision.CollisionEntity;
import src.GameObject; import src.GameObject;
@ -7,11 +9,18 @@ import h3d.scene.Object;
class InteriorObject extends GameObject { class InteriorObject extends GameObject {
public var collider:CollisionEntity; public var collider:CollisionEntity;
public var interiorFile:String;
public var useInstancing = true;
public function new() { public function new() {
super(); super();
} }
public function init(level:MarbleWorld) {
this.identifier = this.interiorFile;
DifBuilder.loadDif(this.interiorFile, cast this);
}
public override function setTransform(transform:Matrix) { public override function setTransform(transform:Matrix) {
super.setTransform(transform); super.setTransform(transform);
collider.setTransform(transform); collider.setTransform(transform);

View file

@ -1,5 +1,6 @@
package; package;
import shapes.SignFinish;
import shapes.Trapdoor; import shapes.Trapdoor;
import shapes.AntiGravity; import shapes.AntiGravity;
import shapes.SuperJump; import shapes.SuperJump;
@ -33,13 +34,13 @@ class Main extends hxd.App {
override function init() { override function init() {
super.init(); super.init();
dtsObj = new Tornado(); dtsObj = new SignFinish();
dtsObj.x = 5; dtsObj.z = 5;
world = new MarbleWorld(s3d); world = new MarbleWorld(s3d);
var db = new InteriorObject(); var db = new InteriorObject();
DifBuilder.loadDif("data/interiors/beginner/training_friction.dif", db); db.interiorFile = "data/interiors/beginner/training_friction.dif";
world.addInterior(db); world.addInterior(db);
var tform = db.getTransform(); var tform = db.getTransform();
tform.setPosition(new Vector(0, 0, 7.5)); tform.setPosition(new Vector(0, 0, 7.5));
@ -86,14 +87,14 @@ class Main extends hxd.App {
world.addDtsObject(dtsObj); world.addDtsObject(dtsObj);
for (i in 0...10) { // for (i in 0...10) {
for (j in 0...10) { // for (j in 0...10) {
var trapdoor = new Tornado(); // var trapdoor = new Tornado();
trapdoor.x = i * 2; // trapdoor.x = i * 2;
trapdoor.y = j * 2; // trapdoor.y = j * 2;
world.addDtsObject(trapdoor); // world.addDtsObject(trapdoor);
} // }
} // }
// for (surf in db.collider.surfaces) { // for (surf in db.collider.surfaces) {
// var surfmin = new CustomObject(cube, mat, s3d); // var surfmin = new CustomObject(cube, mat, s3d);

View file

@ -33,15 +33,22 @@ class MarbleWorld {
public function addInterior(obj:InteriorObject) { public function addInterior(obj:InteriorObject) {
this.interiors.push(obj); this.interiors.push(obj);
obj.init(cast this);
this.collisionWorld.addEntity(obj.collider); this.collisionWorld.addEntity(obj.collider);
this.scene.addChild(obj); if (obj.useInstancing)
this.instanceManager.addObject(obj);
else
this.scene.addChild(obj);
} }
public function addPathedInterior(obj:PathedInterior) { public function addPathedInterior(obj:PathedInterior) {
this.pathedInteriors.push(obj); this.pathedInteriors.push(obj);
obj.init(cast this);
this.collisionWorld.addMovingEntity(obj.collider); this.collisionWorld.addMovingEntity(obj.collider);
this.scene.addChild(obj); if (obj.useInstancing)
obj.init(); this.instanceManager.addObject(obj);
else
this.scene.addChild(obj);
} }
public function addDtsObject(obj:DtsObject) { public function addDtsObject(obj:DtsObject) {
@ -51,7 +58,6 @@ class MarbleWorld {
this.instanceManager.addObject(obj); this.instanceManager.addObject(obj);
} else } else
this.scene.addChild(obj); this.scene.addChild(obj);
// this.instanceManager.addObject(obj);
for (collider in obj.colliders) { for (collider in obj.colliders) {
if (collider != null) if (collider != null)
this.collisionWorld.addEntity(collider); this.collisionWorld.addEntity(collider);

View file

@ -1,5 +1,6 @@
package src; package src;
import src.MarbleWorld;
import h3d.Matrix; import h3d.Matrix;
import h3d.Vector; import h3d.Vector;
import src.Util; import src.Util;
@ -37,7 +38,7 @@ class PathedInterior extends InteriorObject {
super(); super();
} }
public function init() { public override function init(level:MarbleWorld) {
this.computeDuration(); this.computeDuration();
this.reset(); this.reset();
} }

View file

@ -1,5 +1,6 @@
package src; package src;
import h3d.mat.Texture;
import h3d.scene.Object; import h3d.scene.Object;
import sys.FileSystem; import sys.FileSystem;
import sys.io.File; import sys.io.File;
@ -15,6 +16,7 @@ class ResourceLoader {
public static var loader = new Loader(fileSystem); public static var loader = new Loader(fileSystem);
static var interiorResources:Map<String, Dif> = new Map(); static var interiorResources:Map<String, Dif> = new Map();
static var dtsResources:Map<String, DtsFile> = new Map(); static var dtsResources:Map<String, DtsFile> = new Map();
static var textureCache:Map<String, Texture> = new Map();
public static function loadInterior(path:String) { public static function loadInterior(path:String) {
if (interiorResources.exists(path)) if (interiorResources.exists(path))
@ -37,6 +39,17 @@ class ResourceLoader {
} }
} }
public static function getTexture(path:String) {
if (textureCache.exists(path))
return textureCache.get(path);
if (fileSystem.exists(path)) {
var tex = loader.load(path).toTexture();
textureCache.set(path, tex);
return tex;
}
return null;
}
public static function clearInteriorResources() { public static function clearInteriorResources() {
interiorResources = new Map(); interiorResources = new Map();
} }

View file

@ -21,6 +21,14 @@ class CollisionWorld {
var searchdist = (velocity.length() * dt) + radius; var searchdist = (velocity.length() * dt) + radius;
var intersections = this.octree.radiusSearch(position, searchdist); var intersections = this.octree.radiusSearch(position, searchdist);
var box = new Bounds();
box.xMin = position.x - radius;
box.yMin = position.y - radius;
box.zMin = position.z - radius;
box.xMax = position.x + radius;
box.yMax = position.y + radius;
box.zMax = position.z + radius;
var contacts = []; var contacts = [];
for (obj in intersections) { for (obj in intersections) {
@ -31,7 +39,8 @@ class CollisionWorld {
for (obj in dynamicEntities) { for (obj in dynamicEntities) {
if (obj != spherecollision) { if (obj != spherecollision) {
contacts = contacts.concat(obj.sphereIntersection(spherecollision, dt)); if (obj.boundingBox.collide(box))
contacts = contacts.concat(obj.sphereIntersection(spherecollision, dt));
} }
} }
return contacts; return contacts;

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

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