mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-28 05:31:37 +00:00
Add interior instancing and animated textures
This commit is contained in:
parent
4eb5a1fd27
commit
0f3be7d51b
9 changed files with 119 additions and 19 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
23
src/Main.hx
23
src/Main.hx
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
13
src/shapes/SignFinish.hx
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue