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;
import sys.io.File;
import src.MarbleWorld;
import src.GameObject;
import collision.CollisionHull;
@ -70,6 +71,7 @@ class DtsObject extends GameObject {
var level:MarbleWorld;
var materials:Array<Material> = [];
var materialInfos:Map<Material, Array<String>> = new Map();
var matNameOverride:Map<String, String> = new Map();
var sequenceKeyframeOverride:Map<Sequence, Float> = new Map();
@ -312,9 +314,11 @@ class DtsObject extends GameObject {
// TODO USE PBR???
}
} else if (Path.extension(fullName) == "ifl") {
var keyframes = parseIfl(fullName);
this.materialInfos.set(material, keyframes);
// TODO IFL SHIT
} else {
var texture:Texture = ResourceLoader.loader.load(fullName).toImage().toTexture();
var texture:Texture = ResourceLoader.getTexture(fullName);
texture.wrap = Wrap.Repeat;
material.texture = texture;
// 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) {
for (i in 0...this.graphNodes.length) {
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) {
var absTform = this.graphNodes[i].getAbsPos().clone();
if (this.colliders[i] != null)

View file

@ -61,7 +61,7 @@ class InstanceManager {
var isMesh = obj is Mesh;
var minfo:MeshBatchInfo = {
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
}
minfos.push(minfo);

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,6 @@
package src;
import h3d.mat.Texture;
import h3d.scene.Object;
import sys.FileSystem;
import sys.io.File;
@ -15,6 +16,7 @@ class ResourceLoader {
public static var loader = new Loader(fileSystem);
static var interiorResources:Map<String, Dif> = new Map();
static var dtsResources:Map<String, DtsFile> = new Map();
static var textureCache:Map<String, Texture> = new Map();
public static function loadInterior(path:String) {
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() {
interiorResources = new Map();
}

View file

@ -21,6 +21,14 @@ class CollisionWorld {
var searchdist = (velocity.length() * dt) + radius;
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 = [];
for (obj in intersections) {
@ -31,7 +39,8 @@ class CollisionWorld {
for (obj in dynamicEntities) {
if (obj != spherecollision) {
contacts = contacts.concat(obj.sphereIntersection(spherecollision, dt));
if (obj.boundingBox.collide(box))
contacts = contacts.concat(obj.sphereIntersection(spherecollision, dt));
}
}
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;
}
}