mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-12-29 19:32:19 +00:00
finally async resource loading
This commit is contained in:
parent
bac815ebc2
commit
2b9db80b38
31 changed files with 1015 additions and 704 deletions
|
|
@ -25,6 +25,7 @@ import h3d.prim.BigPrimitive;
|
|||
import dif.Interior;
|
||||
import dif.Dif;
|
||||
import src.InteriorObject;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class DifBuilderTriangle {
|
||||
public var texture:String;
|
||||
|
|
@ -97,478 +98,497 @@ class DifBuilder {
|
|||
}
|
||||
];
|
||||
|
||||
public static function loadDif(path:String, itr:InteriorObject, ?so:Int = -1) {
|
||||
var difresource = ResourceLoader.loadInterior(path);
|
||||
difresource.acquire();
|
||||
var dif = difresource.resource;
|
||||
public static function loadDif(path:String, itr:InteriorObject, onFinish:Void->Void, ?so:Int = -1) {
|
||||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
ResourceLoader.loader.load(path).entry.load(() -> {
|
||||
var difresource = ResourceLoader.loadInterior(path);
|
||||
difresource.acquire();
|
||||
var dif = difresource.resource;
|
||||
|
||||
var geo = so == -1 ? dif.interiors[0] : dif.subObjects[so];
|
||||
var geo = so == -1 ? dif.interiors[0] : dif.subObjects[so];
|
||||
|
||||
var hulls = geo.convexHulls;
|
||||
var hulls = geo.convexHulls;
|
||||
|
||||
var triangles = [];
|
||||
var textures = [];
|
||||
var triangles = [];
|
||||
var textures = [];
|
||||
|
||||
var collider = new CollisionEntity(itr);
|
||||
var collider = new CollisionEntity(itr);
|
||||
|
||||
function stripTexName(tex:String) {
|
||||
var dotpos = tex.lastIndexOf(".");
|
||||
var slashpos = tex.lastIndexOf("/") + 1;
|
||||
if (dotpos == -1) {
|
||||
dotpos = tex.length;
|
||||
function stripTexName(tex:String) {
|
||||
var dotpos = tex.lastIndexOf(".");
|
||||
var slashpos = tex.lastIndexOf("/") + 1;
|
||||
if (dotpos == -1) {
|
||||
dotpos = tex.length;
|
||||
}
|
||||
if (slashpos == -1) {
|
||||
slashpos = 0;
|
||||
}
|
||||
return tex.substring(slashpos, dotpos);
|
||||
}
|
||||
if (slashpos == -1) {
|
||||
slashpos = 0;
|
||||
|
||||
var vertexBuckets = new Map<Point3F, Array<VertexBucket>>();
|
||||
|
||||
var edges = [];
|
||||
var colliderSurfaces = [];
|
||||
|
||||
for (i in 0...hulls.length) {
|
||||
var hullTris = [];
|
||||
var hull = hulls[i];
|
||||
|
||||
for (j in hull.surfaceStart...(hull.surfaceStart + hull.surfaceCount)) {
|
||||
var surfaceindex = geo.hullSurfaceIndices[j];
|
||||
var surface = geo.surfaces[surfaceindex];
|
||||
if (surface == null)
|
||||
continue;
|
||||
var planeindex = surface.planeIndex;
|
||||
|
||||
var planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
var plane = geo.planes[planeindex];
|
||||
var normal = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal = normal.scalar(-1);
|
||||
|
||||
var texture = geo.materialList[surface.textureIndex];
|
||||
if (!textures.contains(texture))
|
||||
textures.push(texture);
|
||||
|
||||
var points = geo.points;
|
||||
|
||||
var colliderSurface = new CollisionSurface();
|
||||
colliderSurface.points = [];
|
||||
colliderSurface.normals = [];
|
||||
colliderSurface.indices = [];
|
||||
colliderSurface.edgeData = [];
|
||||
colliderSurface.edgeDots = [];
|
||||
colliderSurface.originalIndices = [];
|
||||
colliderSurface.originalSurfaceIndex = surfaceindex;
|
||||
|
||||
for (k in(surface.windingStart + 2)...(surface.windingStart + surface.windingCount)) {
|
||||
var p1, p2, p3;
|
||||
if ((k - (surface.windingStart + 2)) % 2 == 0) {
|
||||
p1 = points[geo.windings[k]];
|
||||
p2 = points[geo.windings[k - 1]];
|
||||
p3 = points[geo.windings[k - 2]];
|
||||
colliderSurface.originalIndices.push(geo.windings[k]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 1]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 2]);
|
||||
} else {
|
||||
p1 = points[geo.windings[k - 2]];
|
||||
p2 = points[geo.windings[k - 1]];
|
||||
p3 = points[geo.windings[k]];
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 2]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 1]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k]);
|
||||
}
|
||||
|
||||
var e1 = new TriangleEdge(geo.windings[k], geo.windings[k - 1], surfaceindex);
|
||||
var e2 = new TriangleEdge(geo.windings[k - 1], geo.windings[k - 2], surfaceindex);
|
||||
var e3 = new TriangleEdge(geo.windings[k], geo.windings[k - 2], surfaceindex);
|
||||
|
||||
edges.push(e1);
|
||||
edges.push(e2);
|
||||
edges.push(e3);
|
||||
|
||||
var texgen = geo.texGenEQs[surface.texGenIndex];
|
||||
|
||||
var uv1 = new Point2F(p1.x * texgen.planeX.x
|
||||
+ p1.y * texgen.planeX.y
|
||||
+ p1.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p1.x * texgen.planeY.x
|
||||
+ p1.y * texgen.planeY.y
|
||||
+ p1.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
var uv2 = new Point2F(p2.x * texgen.planeX.x
|
||||
+ p2.y * texgen.planeX.y
|
||||
+ p2.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p2.x * texgen.planeY.x
|
||||
+ p2.y * texgen.planeY.y
|
||||
+ p2.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
var uv3 = new Point2F(p3.x * texgen.planeX.x
|
||||
+ p3.y * texgen.planeX.y
|
||||
+ p3.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p3.x * texgen.planeY.x
|
||||
+ p3.y * texgen.planeY.y
|
||||
+ p3.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
|
||||
var tri = new DifBuilderTriangle();
|
||||
tri.texture = texture;
|
||||
tri.normal1 = normal;
|
||||
tri.normal2 = normal;
|
||||
tri.normal3 = normal;
|
||||
tri.p1 = p1;
|
||||
tri.p2 = p2;
|
||||
tri.p3 = p3;
|
||||
tri.uv1 = uv1;
|
||||
tri.uv2 = uv2;
|
||||
tri.uv3 = uv3;
|
||||
triangles.push(tri);
|
||||
hullTris.push(tri);
|
||||
var materialName = stripTexName(texture);
|
||||
var hasMaterialInfo = materialDict.exists(materialName);
|
||||
if (hasMaterialInfo) {
|
||||
var minfo = materialDict.get(materialName);
|
||||
colliderSurface.friction = minfo.friction;
|
||||
colliderSurface.restitution = minfo.restitution;
|
||||
}
|
||||
colliderSurface.points.push(new Vector(-p1.x, p1.y, p1.z));
|
||||
colliderSurface.points.push(new Vector(-p2.x, p2.y, p2.z));
|
||||
colliderSurface.points.push(new Vector(-p3.x, p3.y, p3.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
|
||||
for (v in [p1, p2, p3]) {
|
||||
var buckets = vertexBuckets.get(v);
|
||||
if (buckets == null) {
|
||||
buckets = [];
|
||||
vertexBuckets.set(v, buckets);
|
||||
}
|
||||
|
||||
var bucket:VertexBucket = null;
|
||||
for (j in 0...buckets.length) {
|
||||
bucket = buckets[j];
|
||||
if (normal.dot(bucket.referenceNormal) > Math.cos(Math.PI / 12))
|
||||
break;
|
||||
bucket = null;
|
||||
}
|
||||
if (bucket == null) {
|
||||
bucket = {
|
||||
referenceNormal: normal,
|
||||
triangleIndices: [],
|
||||
normals: []
|
||||
};
|
||||
buckets.push(bucket);
|
||||
}
|
||||
|
||||
bucket.triangleIndices.push(triangles.length - 1);
|
||||
bucket.normals.push(normal);
|
||||
}
|
||||
}
|
||||
|
||||
colliderSurface.generateBoundingBox();
|
||||
collider.addSurface(colliderSurface);
|
||||
colliderSurfaces.push(colliderSurface);
|
||||
}
|
||||
}
|
||||
return tex.substring(slashpos, dotpos);
|
||||
}
|
||||
|
||||
var vertexBuckets = new Map<Point3F, Array<VertexBucket>>();
|
||||
var edgeMap:Map<Int, TriangleEdge> = new Map();
|
||||
var internalEdges:Map<Int, Bool> = new Map();
|
||||
|
||||
var edges = [];
|
||||
var colliderSurfaces = [];
|
||||
var difEdges:Map<Int, Edge> = [];
|
||||
|
||||
for (i in 0...hulls.length) {
|
||||
var hullTris = [];
|
||||
var hull = hulls[i];
|
||||
for (edge in edges) {
|
||||
var edgeHash = edge.index1 >= edge.index2 ? edge.index1 * edge.index1 + edge.index1 + edge.index2 : edge.index1 + edge.index2 * edge.index2;
|
||||
|
||||
for (j in hull.surfaceStart...(hull.surfaceStart + hull.surfaceCount)) {
|
||||
var surfaceindex = geo.hullSurfaceIndices[j];
|
||||
var surface = geo.surfaces[surfaceindex];
|
||||
if (surface == null)
|
||||
if (internalEdges.exists(edgeHash))
|
||||
continue;
|
||||
var planeindex = surface.planeIndex;
|
||||
|
||||
if (edgeMap.exists(edgeHash)) {
|
||||
if (edgeMap[edgeHash].surfaceIndex == edge.surfaceIndex) {
|
||||
// Internal edge
|
||||
internalEdges.set(edgeHash, true);
|
||||
edgeMap.remove(edgeHash);
|
||||
// trace('Removing internal edge: ${edge.index1} ${edge.index2}');
|
||||
} else {
|
||||
var difEdge = new Edge(edge.index1, edge.index2, edge.surfaceIndex, edgeMap[edgeHash].surfaceIndex);
|
||||
difEdges.set(edgeHash, difEdge); // Literal edge
|
||||
}
|
||||
} else {
|
||||
edgeMap.set(edgeHash, edge);
|
||||
}
|
||||
}
|
||||
|
||||
function hashEdge(i1:Int, i2:Int) {
|
||||
return i1 >= i2 ? i1 * i1 + i1 + i2 : i1 + i2 * i2;
|
||||
}
|
||||
|
||||
function getEdgeDot(edge:Edge) {
|
||||
var edgeSurface0 = edge.surfaceIndex0;
|
||||
var surface0 = geo.surfaces[edgeSurface0];
|
||||
|
||||
var planeindex = surface0.planeIndex;
|
||||
|
||||
var planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
var plane = geo.planes[planeindex];
|
||||
var normal = geo.normals[plane.normalIndex];
|
||||
var normal0 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal = normal.scalar(-1);
|
||||
normal0 = normal0.scalar(-1);
|
||||
|
||||
var texture = geo.materialList[surface.textureIndex];
|
||||
if (!textures.contains(texture))
|
||||
textures.push(texture);
|
||||
var edgeSurface1 = edge.surfaceIndex1;
|
||||
var surface1 = geo.surfaces[edgeSurface1];
|
||||
|
||||
var points = geo.points;
|
||||
planeindex = surface1.planeIndex;
|
||||
|
||||
var colliderSurface = new CollisionSurface();
|
||||
colliderSurface.points = [];
|
||||
colliderSurface.normals = [];
|
||||
colliderSurface.indices = [];
|
||||
colliderSurface.edgeData = [];
|
||||
colliderSurface.edgeDots = [];
|
||||
colliderSurface.originalIndices = [];
|
||||
colliderSurface.originalSurfaceIndex = surfaceindex;
|
||||
planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
for (k in (surface.windingStart + 2)...(surface.windingStart + surface.windingCount)) {
|
||||
var p1, p2, p3;
|
||||
if ((k - (surface.windingStart + 2)) % 2 == 0) {
|
||||
p1 = points[geo.windings[k]];
|
||||
p2 = points[geo.windings[k - 1]];
|
||||
p3 = points[geo.windings[k - 2]];
|
||||
colliderSurface.originalIndices.push(geo.windings[k]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 1]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 2]);
|
||||
plane = geo.planes[planeindex];
|
||||
var normal1 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal1 = normal1.scalar(-1);
|
||||
|
||||
var dot = normal0.dot(normal1);
|
||||
|
||||
return dot;
|
||||
}
|
||||
|
||||
function getEdgeNormal(edge:Edge) {
|
||||
var edgeSurface0 = edge.surfaceIndex0;
|
||||
var surface0 = geo.surfaces[edgeSurface0];
|
||||
|
||||
var planeindex = surface0.planeIndex;
|
||||
|
||||
var planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
var plane = geo.planes[planeindex];
|
||||
var normal0 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal0 = normal0.scalar(-1);
|
||||
|
||||
var edgeSurface1 = edge.surfaceIndex1;
|
||||
var surface1 = geo.surfaces[edgeSurface1];
|
||||
|
||||
planeindex = surface1.planeIndex;
|
||||
|
||||
planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
plane = geo.planes[planeindex];
|
||||
var normal1 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal1 = normal1.scalar(-1);
|
||||
|
||||
var norm = normal0.add(normal1).scalarDiv(2).normalized();
|
||||
|
||||
var vec = new Vector(norm.x, norm.y, norm.z);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
for (colliderSurface in colliderSurfaces) {
|
||||
var i = 0;
|
||||
while (i < colliderSurface.indices.length) {
|
||||
var e1e2 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 1]);
|
||||
var e2e3 = hashEdge(colliderSurface.originalIndices[i + 1], colliderSurface.originalIndices[i + 2]);
|
||||
var e1e3 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 2]);
|
||||
|
||||
var edgeData = 0;
|
||||
if (difEdges.exists(e1e2)) {
|
||||
if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 1;
|
||||
}
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e2]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e2]));
|
||||
} else {
|
||||
p1 = points[geo.windings[k - 2]];
|
||||
p2 = points[geo.windings[k - 1]];
|
||||
p3 = points[geo.windings[k]];
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 2]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k - 1]);
|
||||
colliderSurface.originalIndices.push(geo.windings[k]);
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
|
||||
var e1 = new TriangleEdge(geo.windings[k], geo.windings[k - 1], surfaceindex);
|
||||
var e2 = new TriangleEdge(geo.windings[k - 1], geo.windings[k - 2], surfaceindex);
|
||||
var e3 = new TriangleEdge(geo.windings[k], geo.windings[k - 2], surfaceindex);
|
||||
|
||||
edges.push(e1);
|
||||
edges.push(e2);
|
||||
edges.push(e3);
|
||||
|
||||
var texgen = geo.texGenEQs[surface.texGenIndex];
|
||||
|
||||
var uv1 = new Point2F(p1.x * texgen.planeX.x
|
||||
+ p1.y * texgen.planeX.y
|
||||
+ p1.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p1.x * texgen.planeY.x
|
||||
+ p1.y * texgen.planeY.y
|
||||
+ p1.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
var uv2 = new Point2F(p2.x * texgen.planeX.x
|
||||
+ p2.y * texgen.planeX.y
|
||||
+ p2.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p2.x * texgen.planeY.x
|
||||
+ p2.y * texgen.planeY.y
|
||||
+ p2.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
var uv3 = new Point2F(p3.x * texgen.planeX.x
|
||||
+ p3.y * texgen.planeX.y
|
||||
+ p3.z * texgen.planeX.z
|
||||
+ texgen.planeX.d,
|
||||
p3.x * texgen.planeY.x
|
||||
+ p3.y * texgen.planeY.y
|
||||
+ p3.z * texgen.planeY.z
|
||||
+ texgen.planeY.d);
|
||||
|
||||
var tri = new DifBuilderTriangle();
|
||||
tri.texture = texture;
|
||||
tri.normal1 = normal;
|
||||
tri.normal2 = normal;
|
||||
tri.normal3 = normal;
|
||||
tri.p1 = p1;
|
||||
tri.p2 = p2;
|
||||
tri.p3 = p3;
|
||||
tri.uv1 = uv1;
|
||||
tri.uv2 = uv2;
|
||||
tri.uv3 = uv3;
|
||||
triangles.push(tri);
|
||||
hullTris.push(tri);
|
||||
var materialName = stripTexName(texture);
|
||||
var hasMaterialInfo = materialDict.exists(materialName);
|
||||
if (hasMaterialInfo) {
|
||||
var minfo = materialDict.get(materialName);
|
||||
colliderSurface.friction = minfo.friction;
|
||||
colliderSurface.restitution = minfo.restitution;
|
||||
}
|
||||
colliderSurface.points.push(new Vector(-p1.x, p1.y, p1.z));
|
||||
colliderSurface.points.push(new Vector(-p2.x, p2.y, p2.z));
|
||||
colliderSurface.points.push(new Vector(-p3.x, p3.y, p3.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
colliderSurface.indices.push(colliderSurface.indices.length);
|
||||
|
||||
for (v in [p1, p2, p3]) {
|
||||
var buckets = vertexBuckets.get(v);
|
||||
if (buckets == null) {
|
||||
buckets = [];
|
||||
vertexBuckets.set(v, buckets);
|
||||
if (difEdges.exists(e2e3)) {
|
||||
if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 2;
|
||||
}
|
||||
|
||||
var bucket:VertexBucket = null;
|
||||
for (j in 0...buckets.length) {
|
||||
bucket = buckets[j];
|
||||
if (normal.dot(bucket.referenceNormal) > Math.cos(Math.PI / 12))
|
||||
break;
|
||||
bucket = null;
|
||||
}
|
||||
if (bucket == null) {
|
||||
bucket = {
|
||||
referenceNormal: normal,
|
||||
triangleIndices: [],
|
||||
normals: []
|
||||
};
|
||||
buckets.push(bucket);
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e2e3]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e2e3]));
|
||||
// colliderSurface.edgeDots.push(dot);
|
||||
} else {
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
if (difEdges.exists(e1e3)) {
|
||||
if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 4;
|
||||
}
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e3]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e3]));
|
||||
// colliderSurface.edgeDots.push(dot);
|
||||
} else {
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
|
||||
bucket.triangleIndices.push(triangles.length - 1);
|
||||
bucket.normals.push(normal);
|
||||
colliderSurface.edgeData.push(edgeData);
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
for (vtex => buckets in vertexBuckets) {
|
||||
for (i in 0...buckets.length) {
|
||||
var bucket = buckets[i];
|
||||
var avgNormal = new Point3F();
|
||||
|
||||
for (normal in bucket.normals)
|
||||
avgNormal = avgNormal.add(normal);
|
||||
avgNormal = avgNormal.scalarDiv(bucket.normals.length);
|
||||
|
||||
for (j in 0...bucket.triangleIndices.length) {
|
||||
var index = bucket.triangleIndices[j];
|
||||
var tri = triangles[index];
|
||||
if (tri.p1 == vtex)
|
||||
tri.normal1 = avgNormal;
|
||||
if (tri.p2 == vtex)
|
||||
tri.normal2 = avgNormal;
|
||||
if (tri.p3 == vtex)
|
||||
tri.normal3 = avgNormal;
|
||||
}
|
||||
}
|
||||
|
||||
colliderSurface.generateBoundingBox();
|
||||
collider.addSurface(colliderSurface);
|
||||
colliderSurfaces.push(colliderSurface);
|
||||
}
|
||||
}
|
||||
|
||||
var edgeMap:Map<Int, TriangleEdge> = new Map();
|
||||
var internalEdges:Map<Int, Bool> = new Map();
|
||||
var mats = new Map<String, Array<DifBuilderTriangle>>();
|
||||
|
||||
var difEdges:Map<Int, Edge> = [];
|
||||
|
||||
for (edge in edges) {
|
||||
var edgeHash = edge.index1 >= edge.index2 ? edge.index1 * edge.index1 + edge.index1 + edge.index2 : edge.index1 + edge.index2 * edge.index2;
|
||||
|
||||
if (internalEdges.exists(edgeHash))
|
||||
continue;
|
||||
|
||||
if (edgeMap.exists(edgeHash)) {
|
||||
if (edgeMap[edgeHash].surfaceIndex == edge.surfaceIndex) {
|
||||
// Internal edge
|
||||
internalEdges.set(edgeHash, true);
|
||||
edgeMap.remove(edgeHash);
|
||||
// trace('Removing internal edge: ${edge.index1} ${edge.index2}');
|
||||
for (index => value in triangles) {
|
||||
if (mats.exists(value.texture)) {
|
||||
mats[value.texture].push(value);
|
||||
} else {
|
||||
var difEdge = new Edge(edge.index1, edge.index2, edge.surfaceIndex, edgeMap[edgeHash].surfaceIndex);
|
||||
difEdges.set(edgeHash, difEdge); // Literal edge
|
||||
}
|
||||
} else {
|
||||
edgeMap.set(edgeHash, edge);
|
||||
}
|
||||
}
|
||||
|
||||
function hashEdge(i1:Int, i2:Int) {
|
||||
return i1 >= i2 ? i1 * i1 + i1 + i2 : i1 + i2 * i2;
|
||||
}
|
||||
|
||||
function getEdgeDot(edge:Edge) {
|
||||
var edgeSurface0 = edge.surfaceIndex0;
|
||||
var surface0 = geo.surfaces[edgeSurface0];
|
||||
|
||||
var planeindex = surface0.planeIndex;
|
||||
|
||||
var planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
var plane = geo.planes[planeindex];
|
||||
var normal0 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal0 = normal0.scalar(-1);
|
||||
|
||||
var edgeSurface1 = edge.surfaceIndex1;
|
||||
var surface1 = geo.surfaces[edgeSurface1];
|
||||
|
||||
planeindex = surface1.planeIndex;
|
||||
|
||||
planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
plane = geo.planes[planeindex];
|
||||
var normal1 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal1 = normal1.scalar(-1);
|
||||
|
||||
var dot = normal0.dot(normal1);
|
||||
|
||||
return dot;
|
||||
}
|
||||
|
||||
function getEdgeNormal(edge:Edge) {
|
||||
var edgeSurface0 = edge.surfaceIndex0;
|
||||
var surface0 = geo.surfaces[edgeSurface0];
|
||||
|
||||
var planeindex = surface0.planeIndex;
|
||||
|
||||
var planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
var plane = geo.planes[planeindex];
|
||||
var normal0 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal0 = normal0.scalar(-1);
|
||||
|
||||
var edgeSurface1 = edge.surfaceIndex1;
|
||||
var surface1 = geo.surfaces[edgeSurface1];
|
||||
|
||||
planeindex = surface1.planeIndex;
|
||||
|
||||
planeFlipped = (planeindex & 0x8000) == 0x8000;
|
||||
if (planeFlipped)
|
||||
planeindex &= ~0x8000;
|
||||
|
||||
plane = geo.planes[planeindex];
|
||||
var normal1 = geo.normals[plane.normalIndex];
|
||||
|
||||
if (planeFlipped)
|
||||
normal1 = normal1.scalar(-1);
|
||||
|
||||
var norm = normal0.add(normal1).scalarDiv(2).normalized();
|
||||
|
||||
var vec = new Vector(norm.x, norm.y, norm.z);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
for (colliderSurface in colliderSurfaces) {
|
||||
var i = 0;
|
||||
while (i < colliderSurface.indices.length) {
|
||||
var e1e2 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 1]);
|
||||
var e2e3 = hashEdge(colliderSurface.originalIndices[i + 1], colliderSurface.originalIndices[i + 2]);
|
||||
var e1e3 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 2]);
|
||||
|
||||
var edgeData = 0;
|
||||
if (difEdges.exists(e1e2)) {
|
||||
if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 1;
|
||||
}
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e2]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e2]));
|
||||
} else {
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
if (difEdges.exists(e2e3)) {
|
||||
if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 2;
|
||||
}
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e2e3]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e2e3]));
|
||||
// colliderSurface.edgeDots.push(dot);
|
||||
} else {
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
if (difEdges.exists(e1e3)) {
|
||||
if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) {
|
||||
edgeData |= 4;
|
||||
}
|
||||
colliderSurface.edgeDots.push(getEdgeDot(difEdges[e1e3]));
|
||||
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e3]));
|
||||
// colliderSurface.edgeDots.push(dot);
|
||||
} else {
|
||||
colliderSurface.edgeDots.push(0);
|
||||
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
|
||||
}
|
||||
|
||||
colliderSurface.edgeData.push(edgeData);
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
for (vtex => buckets in vertexBuckets) {
|
||||
for (i in 0...buckets.length) {
|
||||
var bucket = buckets[i];
|
||||
var avgNormal = new Point3F();
|
||||
|
||||
for (normal in bucket.normals)
|
||||
avgNormal = avgNormal.add(normal);
|
||||
avgNormal = avgNormal.scalarDiv(bucket.normals.length);
|
||||
|
||||
for (j in 0...bucket.triangleIndices.length) {
|
||||
var index = bucket.triangleIndices[j];
|
||||
var tri = triangles[index];
|
||||
if (tri.p1 == vtex)
|
||||
tri.normal1 = avgNormal;
|
||||
if (tri.p2 == vtex)
|
||||
tri.normal2 = avgNormal;
|
||||
if (tri.p3 == vtex)
|
||||
tri.normal3 = avgNormal;
|
||||
mats.set(value.texture, [value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mats = new Map<String, Array<DifBuilderTriangle>>();
|
||||
collider.difEdgeMap = difEdges;
|
||||
collider.finalize();
|
||||
itr.collider = collider;
|
||||
|
||||
for (index => value in triangles) {
|
||||
if (mats.exists(value.texture)) {
|
||||
mats[value.texture].push(value);
|
||||
} else {
|
||||
mats.set(value.texture, [value]);
|
||||
}
|
||||
}
|
||||
function canFindTex(tex:String) {
|
||||
if (["NULL"].contains(tex)) {
|
||||
return false;
|
||||
}
|
||||
if (tex.indexOf('/') != -1) {
|
||||
tex = tex.split('/')[1];
|
||||
}
|
||||
|
||||
collider.difEdgeMap = difEdges;
|
||||
collider.finalize();
|
||||
itr.collider = collider;
|
||||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return true;
|
||||
}
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function canFindTex(tex:String) {
|
||||
if (["NULL"].contains(tex)) {
|
||||
return false;
|
||||
}
|
||||
if (tex.indexOf('/') != -1) {
|
||||
tex = tex.split('/')[1];
|
||||
|
||||
function tex(tex:String):String {
|
||||
if (tex.indexOf('/') != -1) {
|
||||
tex = tex.split('/')[1];
|
||||
}
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return Path.directory(path) + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return Path.directory(path) + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return prevDir + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
return prevDir + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return true;
|
||||
}
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return true;
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
return true;
|
||||
var loadtexs = [];
|
||||
for (grp => tris in mats) {
|
||||
if (canFindTex(grp)) {
|
||||
loadtexs.push(tex(grp));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
var worker = new ResourceLoaderWorker(() -> {
|
||||
for (grp => tris in mats) {
|
||||
var points = [];
|
||||
var normals = [];
|
||||
var uvs = [];
|
||||
|
||||
function tex(tex:String):String {
|
||||
if (tex.indexOf('/') != -1) {
|
||||
tex = tex.split('/')[1];
|
||||
for (tri in tris) {
|
||||
var p1 = new Point(-tri.p1.x, tri.p1.y, tri.p1.z);
|
||||
var p2 = new Point(-tri.p2.x, tri.p2.y, tri.p2.z);
|
||||
var p3 = new Point(-tri.p3.x, tri.p3.y, tri.p3.z);
|
||||
var n1 = new Point(-tri.normal1.x, tri.normal1.y, tri.normal1.z);
|
||||
var n2 = new Point(-tri.normal2.x, tri.normal2.y, tri.normal2.z);
|
||||
var n3 = new Point(-tri.normal3.x, tri.normal3.y, tri.normal3.z);
|
||||
var uv1 = new UV(tri.uv1.x, tri.uv1.y);
|
||||
var uv2 = new UV(tri.uv2.x, tri.uv2.y);
|
||||
var uv3 = new UV(tri.uv3.x, tri.uv3.y);
|
||||
points.push(p3);
|
||||
points.push(p2);
|
||||
points.push(p1);
|
||||
normals.push(n3);
|
||||
normals.push(n2);
|
||||
normals.push(n1);
|
||||
uvs.push(uv3);
|
||||
uvs.push(uv2);
|
||||
uvs.push(uv1);
|
||||
}
|
||||
|
||||
var prim = new Polygon(points);
|
||||
prim.uvs = uvs;
|
||||
prim.normals = normals;
|
||||
|
||||
var material:Material;
|
||||
var texture:Texture;
|
||||
if (canFindTex(grp)) {
|
||||
texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture();
|
||||
texture.wrap = Wrap.Repeat;
|
||||
texture.mipMap = Nearest;
|
||||
material = h3d.mat.Material.create(texture);
|
||||
} else {
|
||||
material = Material.create();
|
||||
}
|
||||
material.shadows = false;
|
||||
material.receiveShadows = true;
|
||||
// material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
|
||||
// material.mainPass.wireframe = true;
|
||||
|
||||
var mesh = new Mesh(prim, material, itr);
|
||||
}
|
||||
|
||||
difresource.release();
|
||||
onFinish();
|
||||
});
|
||||
for (f in loadtexs) {
|
||||
worker.loadFile(f);
|
||||
}
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".jpg")) {
|
||||
return Path.directory(path) + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(Path.directory(path) + "/" + tex + ".png")) {
|
||||
return Path.directory(path) + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
var prevDir = Path.directory(Path.directory(path));
|
||||
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".jpg")) {
|
||||
return prevDir + "/" + tex + ".jpg";
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(prevDir + "/" + tex + ".png")) {
|
||||
return prevDir + "/" + tex + ".png";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
for (grp => tris in mats) {
|
||||
var points = [];
|
||||
var normals = [];
|
||||
var uvs = [];
|
||||
|
||||
for (tri in tris) {
|
||||
var p1 = new Point(-tri.p1.x, tri.p1.y, tri.p1.z);
|
||||
var p2 = new Point(-tri.p2.x, tri.p2.y, tri.p2.z);
|
||||
var p3 = new Point(-tri.p3.x, tri.p3.y, tri.p3.z);
|
||||
var n1 = new Point(-tri.normal1.x, tri.normal1.y, tri.normal1.z);
|
||||
var n2 = new Point(-tri.normal2.x, tri.normal2.y, tri.normal2.z);
|
||||
var n3 = new Point(-tri.normal3.x, tri.normal3.y, tri.normal3.z);
|
||||
var uv1 = new UV(tri.uv1.x, tri.uv1.y);
|
||||
var uv2 = new UV(tri.uv2.x, tri.uv2.y);
|
||||
var uv3 = new UV(tri.uv3.x, tri.uv3.y);
|
||||
points.push(p3);
|
||||
points.push(p2);
|
||||
points.push(p1);
|
||||
normals.push(n3);
|
||||
normals.push(n2);
|
||||
normals.push(n1);
|
||||
uvs.push(uv3);
|
||||
uvs.push(uv2);
|
||||
uvs.push(uv1);
|
||||
}
|
||||
|
||||
var prim = new Polygon(points);
|
||||
prim.uvs = uvs;
|
||||
prim.normals = normals;
|
||||
|
||||
var material:Material;
|
||||
var texture:Texture;
|
||||
if (canFindTex(grp)) {
|
||||
texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture();
|
||||
texture.wrap = Wrap.Repeat;
|
||||
texture.mipMap = Nearest;
|
||||
material = h3d.mat.Material.create(texture);
|
||||
} else {
|
||||
material = Material.create();
|
||||
}
|
||||
material.shadows = false;
|
||||
material.receiveShadows = true;
|
||||
// material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
|
||||
// material.mainPass.wireframe = true;
|
||||
|
||||
var mesh = new Mesh(prim, material, itr);
|
||||
}
|
||||
|
||||
difresource.release();
|
||||
worker.run();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class DtsObject extends GameObject {
|
|||
super();
|
||||
}
|
||||
|
||||
public function init(level:MarbleWorld) {
|
||||
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
this.dtsResource = ResourceLoader.loadDts(this.dtsPath);
|
||||
this.dtsResource.acquire();
|
||||
this.dts = this.dtsResource.resource;
|
||||
|
|
@ -340,6 +340,8 @@ class DtsObject extends GameObject {
|
|||
for (i in 0...graphNodes.length) {
|
||||
this.dirtyTransforms.push(true);
|
||||
}
|
||||
|
||||
onFinish();
|
||||
}
|
||||
|
||||
function computeMaterials() {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ class InteriorObject extends GameObject {
|
|||
this.isCollideable = true;
|
||||
}
|
||||
|
||||
public function init(level:MarbleWorld) {
|
||||
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
this.identifier = this.interiorFile;
|
||||
this.level = level;
|
||||
DifBuilder.loadDif(this.interiorFile, cast this);
|
||||
DifBuilder.loadDif(this.interiorFile, cast this, onFinish);
|
||||
}
|
||||
|
||||
public override function setTransform(transform:Matrix) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import src.CameraController;
|
|||
import src.Resource;
|
||||
import h3d.mat.Texture;
|
||||
import collision.CCDCollision.TraceInfo;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class Move {
|
||||
public var d:Vector;
|
||||
|
|
@ -228,7 +229,7 @@ class Marble extends GameObject {
|
|||
this.helicopterSound.pause = true;
|
||||
}
|
||||
|
||||
public function init(level:MarbleWorld) {
|
||||
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
this.level = level;
|
||||
this.forcefield = new DtsObject();
|
||||
this.forcefield.dtsPath = "data/shapes/images/glow_bounce.dts";
|
||||
|
|
@ -240,7 +241,6 @@ class Marble extends GameObject {
|
|||
this.forcefield.y = 1e8;
|
||||
this.forcefield.z = 1e8;
|
||||
this.forcefield.isBoundingBoxCollideable = false;
|
||||
level.addDtsObject(this.forcefield);
|
||||
|
||||
this.helicopter = new DtsObject();
|
||||
this.helicopter.dtsPath = "data/shapes/images/helicopter.dts";
|
||||
|
|
@ -252,7 +252,11 @@ class Marble extends GameObject {
|
|||
this.helicopter.x = 1e8;
|
||||
this.helicopter.y = 1e8;
|
||||
this.helicopter.z = 1e8;
|
||||
level.addDtsObject(this.helicopter);
|
||||
|
||||
var worker = new ResourceLoaderWorker(onFinish);
|
||||
worker.addTask(fwd -> level.addDtsObject(this.forcefield, fwd));
|
||||
worker.addTask(fwd -> level.addDtsObject(this.helicopter, fwd));
|
||||
worker.run();
|
||||
}
|
||||
|
||||
function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) {
|
||||
|
|
|
|||
|
|
@ -84,6 +84,22 @@ class MarbleGame {
|
|||
};
|
||||
@:privateAccess Key.keyPressed[buttonCode] = -Key.getFrame();
|
||||
});
|
||||
canvas.addEventListener('mousedown', (e:js.html.MouseEvent) -> {
|
||||
var buttonCode = switch (e.button) {
|
||||
case 1: 2;
|
||||
case 2: 1;
|
||||
case x: x;
|
||||
};
|
||||
@:privateAccess Key.keyPressed[buttonCode] = Key.getFrame();
|
||||
});
|
||||
canvas.addEventListener('mouseup', (e:js.html.MouseEvent) -> {
|
||||
var buttonCode = switch (e.button) {
|
||||
case 1: 2;
|
||||
case 2: 1;
|
||||
case x: x;
|
||||
};
|
||||
@:privateAccess Key.keyPressed[buttonCode] = -Key.getFrame();
|
||||
});
|
||||
pointercontainer.addEventListener('keydown', (e:js.html.KeyboardEvent) -> {
|
||||
var buttonCode = (e.keyCode);
|
||||
@:privateAccess Key.keyPressed[buttonCode] = Key.getFrame();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import hxd.impl.Air3File.FileSeek;
|
||||
import gui.Canvas;
|
||||
import hxd.snd.Channel;
|
||||
import hxd.res.Sound;
|
||||
|
|
@ -71,6 +72,7 @@ import collision.CollisionWorld;
|
|||
import src.Marble;
|
||||
import src.Resource;
|
||||
import src.ProfilerUI;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class MarbleWorld extends Scheduler {
|
||||
public var collisionWorld:CollisionWorld;
|
||||
|
|
@ -122,7 +124,7 @@ class MarbleWorld extends Scheduler {
|
|||
var orientationChangeTime = -1e8;
|
||||
var oldOrientationQuat = new Quat();
|
||||
|
||||
var resourceLoadFuncs:Array<Void->Void> = [];
|
||||
var resourceLoadFuncs:Array<(() -> Void)->Void> = [];
|
||||
|
||||
/** The new target camera orientation quat */
|
||||
public var newOrientationQuat = new Quat();
|
||||
|
|
@ -176,8 +178,16 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.resourceLoadFuncs.push(() -> {
|
||||
this.mission.load();
|
||||
scanMission(this.mission.root);
|
||||
this.resourceLoadFuncs.push(fwd -> this.initScene(fwd));
|
||||
this.resourceLoadFuncs.push(fwd -> this.initMarble(fwd));
|
||||
this.resourceLoadFuncs.push(fwd -> {
|
||||
this.addSimGroup(this.mission.root);
|
||||
this._loadingLength = resourceLoadFuncs.length;
|
||||
fwd();
|
||||
});
|
||||
this.resourceLoadFuncs.push(fwd -> {
|
||||
this.playGui.init(this.scene2d);
|
||||
var musicFileName = [
|
||||
'data/sound/groovepolice.ogg',
|
||||
|
|
@ -185,15 +195,8 @@ class MarbleWorld extends Scheduler {
|
|||
'data/sound/beach party.ogg'
|
||||
][(mission.index + 1) % 3];
|
||||
AudioManager.playMusic(ResourceLoader.getResource(musicFileName, ResourceLoader.getAudio, this.soundResources));
|
||||
fwd();
|
||||
});
|
||||
this.resourceLoadFuncs.push(() -> {
|
||||
this.addSimGroup(this.mission.root);
|
||||
this._loadingLength = resourceLoadFuncs.length;
|
||||
});
|
||||
this.resourceLoadFuncs.push(() -> this.initMarble());
|
||||
this.resourceLoadFuncs.push(() -> this.initScene());
|
||||
this.resourceLoadFuncs.push(() -> scanMission(this.mission.root));
|
||||
this.resourceLoadFuncs.push(() -> this.mission.load());
|
||||
this._loadingLength = resourceLoadFuncs.length;
|
||||
}
|
||||
|
||||
|
|
@ -205,53 +208,103 @@ class MarbleWorld extends Scheduler {
|
|||
start();
|
||||
}
|
||||
|
||||
public function initScene() {
|
||||
public function initScene(onFinish:Void->Void) {
|
||||
this.collisionWorld = new CollisionWorld();
|
||||
this.playGui = new PlayGui();
|
||||
this.instanceManager = new InstanceManager(scene);
|
||||
this.particleManager = new ParticleManager(cast this);
|
||||
|
||||
var renderer = cast(this.scene.renderer, h3d.scene.fwd.Renderer);
|
||||
|
||||
for (element in mission.root.elements) {
|
||||
if (element._type != MissionElementType.Sun)
|
||||
continue;
|
||||
|
||||
var sunElement:MissionElementSun = cast element;
|
||||
|
||||
var directionalColor = MisParser.parseVector4(sunElement.color);
|
||||
var ambientColor = MisParser.parseVector4(sunElement.ambient);
|
||||
var sunDirection = MisParser.parseVector3(sunElement.direction);
|
||||
sunDirection.x = -sunDirection.x;
|
||||
// sunDirection.z = -sunDirection.z;
|
||||
var ls = cast(scene.lightSystem, h3d.scene.fwd.LightSystem);
|
||||
|
||||
ls.ambientLight.load(ambientColor);
|
||||
|
||||
var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap);
|
||||
shadow.power = 0.5;
|
||||
shadow.mode = Dynamic;
|
||||
shadow.minDist = 0.1;
|
||||
shadow.maxDist = 200;
|
||||
shadow.bias = 0;
|
||||
|
||||
var sunlight = new DirLight(sunDirection, scene);
|
||||
sunlight.color = directionalColor;
|
||||
}
|
||||
|
||||
// var skyElement:MissionElementSky = cast this.mission.root.elements.filter((element) -> element._type == MissionElementType.Sky)[0];
|
||||
|
||||
var worker = new ResourceLoaderWorker(() -> {
|
||||
var renderer = cast(this.scene.renderer, h3d.scene.fwd.Renderer);
|
||||
|
||||
for (element in mission.root.elements) {
|
||||
if (element._type != MissionElementType.Sun)
|
||||
continue;
|
||||
|
||||
var sunElement:MissionElementSun = cast element;
|
||||
|
||||
var directionalColor = MisParser.parseVector4(sunElement.color);
|
||||
var ambientColor = MisParser.parseVector4(sunElement.ambient);
|
||||
var sunDirection = MisParser.parseVector3(sunElement.direction);
|
||||
sunDirection.x = -sunDirection.x;
|
||||
// sunDirection.z = -sunDirection.z;
|
||||
var ls = cast(scene.lightSystem, h3d.scene.fwd.LightSystem);
|
||||
|
||||
ls.ambientLight.load(ambientColor);
|
||||
|
||||
var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap);
|
||||
shadow.power = 0.5;
|
||||
shadow.mode = Dynamic;
|
||||
shadow.minDist = 0.1;
|
||||
shadow.maxDist = 200;
|
||||
shadow.bias = 0;
|
||||
|
||||
var sunlight = new DirLight(sunDirection, scene);
|
||||
sunlight.color = directionalColor;
|
||||
}
|
||||
|
||||
onFinish();
|
||||
});
|
||||
var filestoload = [
|
||||
"particles/bubble.png",
|
||||
"particles/saturn.png",
|
||||
"particles/smoke.png",
|
||||
"particles/spark.png",
|
||||
"particles/star.png",
|
||||
"particles/twirl.png",
|
||||
"skies/sky_day.dml"
|
||||
];
|
||||
|
||||
for (file in filestoload) {
|
||||
worker.loadFile(file);
|
||||
}
|
||||
|
||||
this.sky = new Sky();
|
||||
|
||||
sky.dmlPath = "data/skies/sky_day.dml";
|
||||
|
||||
sky.init(cast this);
|
||||
scene.addChild(sky);
|
||||
worker.addTask(fwd -> sky.init(cast this, fwd));
|
||||
worker.addTask(fwd -> {
|
||||
scene.addChild(sky);
|
||||
return fwd();
|
||||
});
|
||||
|
||||
worker.run();
|
||||
}
|
||||
|
||||
public function initMarble() {
|
||||
var marble = new Marble();
|
||||
marble.controllable = true;
|
||||
this.addMarble(marble);
|
||||
public function initMarble(onFinish:Void->Void) {
|
||||
var worker = new ResourceLoaderWorker(onFinish);
|
||||
var marblefiles = [
|
||||
"particles/star.png",
|
||||
"particles/smoke.png",
|
||||
"sound/rolling_hard.wav",
|
||||
"sound/sliding.wav",
|
||||
"sound/superbounceactive.wav",
|
||||
"sound/forcefield.wav",
|
||||
"sound/use_gyrocopter.wav",
|
||||
"sound/bumperding1.wav",
|
||||
"sound/bumper1.wav",
|
||||
"sound/jump.wav",
|
||||
"sound/bouncehard1.wav",
|
||||
"sound/bouncehard2.wav",
|
||||
"sound/bouncehard3.wav",
|
||||
"sound/bouncehard4.wav",
|
||||
"sound/spawn.wav",
|
||||
"sound/ready.wav",
|
||||
"sound/set.wav",
|
||||
"sound/go.wav"
|
||||
];
|
||||
for (file in marblefiles) {
|
||||
worker.loadFile(file);
|
||||
}
|
||||
worker.addTask(fwd -> {
|
||||
var marble = new Marble();
|
||||
marble.controllable = true;
|
||||
this.addMarble(marble, fwd);
|
||||
});
|
||||
worker.run();
|
||||
}
|
||||
|
||||
public function start() {
|
||||
|
|
@ -378,18 +431,23 @@ class MarbleWorld extends Scheduler {
|
|||
public function addSimGroup(simGroup:MissionElementSimGroup) {
|
||||
if (simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior).length != 0) {
|
||||
// Create the pathed interior
|
||||
resourceLoadFuncs.push(() -> {
|
||||
var pathedInterior = src.PathedInterior.createFromSimGroup(simGroup, cast this);
|
||||
this.addPathedInterior(pathedInterior);
|
||||
if (pathedInterior == null)
|
||||
return;
|
||||
resourceLoadFuncs.push(fwd -> {
|
||||
src.PathedInterior.createFromSimGroup(simGroup, cast this, pathedInterior -> {
|
||||
this.addPathedInterior(pathedInterior, () -> {
|
||||
if (pathedInterior == null) {
|
||||
fwd();
|
||||
return;
|
||||
}
|
||||
|
||||
// if (pathedInterior.hasCollision)
|
||||
// this.physics.addInterior(pathedInterior);
|
||||
for (trigger in pathedInterior.triggers) {
|
||||
this.triggers.push(trigger);
|
||||
this.collisionWorld.addEntity(trigger.collider);
|
||||
}
|
||||
// if (pathedInterior.hasCollision)
|
||||
// this.physics.addInterior(pathedInterior);
|
||||
for (trigger in pathedInterior.triggers) {
|
||||
this.triggers.push(trigger);
|
||||
this.collisionWorld.addEntity(trigger.collider);
|
||||
}
|
||||
fwd();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
|
|
@ -400,55 +458,61 @@ class MarbleWorld extends Scheduler {
|
|||
case MissionElementType.SimGroup:
|
||||
this.addSimGroup(cast element);
|
||||
case MissionElementType.InteriorInstance:
|
||||
resourceLoadFuncs.push(() -> this.addInteriorFromMis(cast element));
|
||||
resourceLoadFuncs.push(fwd -> this.addInteriorFromMis(cast element, fwd));
|
||||
case MissionElementType.StaticShape:
|
||||
resourceLoadFuncs.push(() -> this.addStaticShape(cast element));
|
||||
resourceLoadFuncs.push(fwd -> this.addStaticShape(cast element, fwd));
|
||||
case MissionElementType.Item:
|
||||
resourceLoadFuncs.push(() -> this.addItem(cast element));
|
||||
resourceLoadFuncs.push(fwd -> this.addItem(cast element, fwd));
|
||||
case MissionElementType.Trigger:
|
||||
resourceLoadFuncs.push(() -> this.addTrigger(cast element));
|
||||
resourceLoadFuncs.push(fwd -> this.addTrigger(cast element, fwd));
|
||||
case MissionElementType.TSStatic:
|
||||
resourceLoadFuncs.push(() -> this.addTSStatic(cast element));
|
||||
resourceLoadFuncs.push(fwd -> this.addTSStatic(cast element, fwd));
|
||||
case MissionElementType.ParticleEmitterNode:
|
||||
resourceLoadFuncs.push(() -> this.addParticleEmitterNode(cast element));
|
||||
resourceLoadFuncs.push(fwd -> {
|
||||
this.addParticleEmitterNode(cast element);
|
||||
fwd();
|
||||
});
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addInteriorFromMis(element:MissionElementInteriorInstance) {
|
||||
public function addInteriorFromMis(element:MissionElementInteriorInstance, onFinish:Void->Void) {
|
||||
var difPath = this.mission.getDifPath(element.interiorfile);
|
||||
if (difPath == "")
|
||||
if (difPath == "") {
|
||||
onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
var interior = new InteriorObject();
|
||||
interior.interiorFile = difPath;
|
||||
// DifBuilder.loadDif(difPath, interior);
|
||||
// this.interiors.push(interior);
|
||||
this.addInterior(interior);
|
||||
this.addInterior(interior, () -> {
|
||||
var interiorPosition = MisParser.parseVector3(element.position);
|
||||
interiorPosition.x = -interiorPosition.x;
|
||||
var interiorRotation = MisParser.parseRotation(element.rotation);
|
||||
interiorRotation.x = -interiorRotation.x;
|
||||
interiorRotation.w = -interiorRotation.w;
|
||||
var interiorScale = MisParser.parseVector3(element.scale);
|
||||
// var hasCollision = interiorScale.x != = 0 && interiorScale.y != = 0 && interiorScale.z != = 0; // Don't want to add buggy geometry
|
||||
|
||||
var interiorPosition = MisParser.parseVector3(element.position);
|
||||
interiorPosition.x = -interiorPosition.x;
|
||||
var interiorRotation = MisParser.parseRotation(element.rotation);
|
||||
interiorRotation.x = -interiorRotation.x;
|
||||
interiorRotation.w = -interiorRotation.w;
|
||||
var interiorScale = MisParser.parseVector3(element.scale);
|
||||
// var hasCollision = interiorScale.x != = 0 && interiorScale.y != = 0 && interiorScale.z != = 0; // Don't want to add buggy geometry
|
||||
// Fix zero-volume interiors so they receive correct lighting
|
||||
if (interiorScale.x == 0)
|
||||
interiorScale.x = 0.0001;
|
||||
if (interiorScale.y == 0)
|
||||
interiorScale.y = 0.0001;
|
||||
if (interiorScale.z == 0)
|
||||
interiorScale.z = 0.0001;
|
||||
|
||||
// Fix zero-volume interiors so they receive correct lighting
|
||||
if (interiorScale.x == 0)
|
||||
interiorScale.x = 0.0001;
|
||||
if (interiorScale.y == 0)
|
||||
interiorScale.y = 0.0001;
|
||||
if (interiorScale.z == 0)
|
||||
interiorScale.z = 0.0001;
|
||||
var mat = new Matrix();
|
||||
interiorRotation.toMatrix(mat);
|
||||
mat.scale(interiorScale.x, interiorScale.y, interiorScale.z);
|
||||
mat.setPosition(interiorPosition);
|
||||
|
||||
var mat = new Matrix();
|
||||
interiorRotation.toMatrix(mat);
|
||||
mat.scale(interiorScale.x, interiorScale.y, interiorScale.z);
|
||||
mat.setPosition(interiorPosition);
|
||||
|
||||
interior.setTransform(mat);
|
||||
interior.setTransform(mat);
|
||||
onFinish();
|
||||
});
|
||||
|
||||
// interior.setTransform(interiorPosition, interiorRotation, interiorScale);
|
||||
|
||||
|
|
@ -457,7 +521,7 @@ class MarbleWorld extends Scheduler {
|
|||
// this.physics.addInterior(interior);
|
||||
}
|
||||
|
||||
public function addStaticShape(element:MissionElementStaticShape) {
|
||||
public function addStaticShape(element:MissionElementStaticShape, onFinish:Void->Void) {
|
||||
var shape:DtsObject = null;
|
||||
|
||||
// Add the correct shape based on type
|
||||
|
|
@ -509,6 +573,7 @@ class MarbleWorld extends Scheduler {
|
|||
else if (dataBlockLowerCase == "oilslick")
|
||||
shape = new Oilslick();
|
||||
else {
|
||||
onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -531,15 +596,16 @@ class MarbleWorld extends Scheduler {
|
|||
mat.scale(shapeScale.x, shapeScale.y, shapeScale.z);
|
||||
mat.setPosition(shapePosition);
|
||||
|
||||
this.addDtsObject(shape);
|
||||
|
||||
shape.setTransform(mat);
|
||||
this.addDtsObject(shape, () -> {
|
||||
shape.setTransform(mat);
|
||||
onFinish();
|
||||
});
|
||||
|
||||
// else if (dataBlockLowerCase == "pushbutton")
|
||||
// shape = new PushButton();
|
||||
}
|
||||
|
||||
public function addItem(element:MissionElementItem) {
|
||||
public function addItem(element:MissionElementItem, onFinish:Void->Void) {
|
||||
var shape:DtsObject = null;
|
||||
|
||||
// Add the correct shape based on type
|
||||
|
|
@ -585,6 +651,7 @@ class MarbleWorld extends Scheduler {
|
|||
else if (dataBlockLowerCase == "oilslick")
|
||||
shape = new Oilslick();
|
||||
else {
|
||||
onFinish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -607,12 +674,13 @@ class MarbleWorld extends Scheduler {
|
|||
mat.scale(shapeScale.x, shapeScale.y, shapeScale.z);
|
||||
mat.setPosition(shapePosition);
|
||||
|
||||
this.addDtsObject(shape);
|
||||
|
||||
shape.setTransform(mat);
|
||||
this.addDtsObject(shape, () -> {
|
||||
shape.setTransform(mat);
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addTrigger(element:MissionElementTrigger) {
|
||||
public function addTrigger(element:MissionElementTrigger, onFinish:Void->Void) {
|
||||
var trigger:Trigger = null;
|
||||
|
||||
// Create a trigger based on type
|
||||
|
|
@ -625,12 +693,14 @@ class MarbleWorld extends Scheduler {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
this.triggers.push(trigger);
|
||||
this.collisionWorld.addEntity(trigger.collider);
|
||||
trigger.init(() -> {
|
||||
this.triggers.push(trigger);
|
||||
this.collisionWorld.addEntity(trigger.collider);
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addTSStatic(element:MissionElementTSStatic) {
|
||||
public function addTSStatic(element:MissionElementTSStatic, onFinish:Void->Void) {
|
||||
// !! WARNING - UNTESTED !!
|
||||
var shapeName = element.shapename;
|
||||
var index = shapeName.indexOf('data/');
|
||||
|
|
@ -660,67 +730,80 @@ class MarbleWorld extends Scheduler {
|
|||
mat.scale(shapeScale.x, shapeScale.y, shapeScale.z);
|
||||
mat.setPosition(shapePosition);
|
||||
|
||||
this.addDtsObject(tsShape);
|
||||
|
||||
tsShape.setTransform(mat);
|
||||
this.addDtsObject(tsShape, () -> {
|
||||
tsShape.setTransform(mat);
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addParticleEmitterNode(element:MissionElementParticleEmitterNode) {
|
||||
// TODO THIS SHIT
|
||||
}
|
||||
|
||||
public function addInterior(obj:InteriorObject) {
|
||||
public function addInterior(obj:InteriorObject, onFinish:Void->Void) {
|
||||
this.interiors.push(obj);
|
||||
obj.init(cast this);
|
||||
this.collisionWorld.addEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
this.scene.addChild(obj);
|
||||
obj.init(cast this, () -> {
|
||||
this.collisionWorld.addEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
this.scene.addChild(obj);
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addPathedInterior(obj:PathedInterior) {
|
||||
public function addPathedInterior(obj:PathedInterior, onFinish:Void->Void) {
|
||||
this.pathedInteriors.push(obj);
|
||||
obj.init(cast this);
|
||||
this.collisionWorld.addMovingEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
this.scene.addChild(obj);
|
||||
obj.init(cast this, () -> {
|
||||
this.collisionWorld.addMovingEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
this.scene.addChild(obj);
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addDtsObject(obj:DtsObject) {
|
||||
public function addDtsObject(obj:DtsObject, onFinish:Void->Void) {
|
||||
this.dtsObjects.push(obj);
|
||||
if (obj is ForceObject) {
|
||||
this.forceObjects.push(cast obj);
|
||||
}
|
||||
obj.init(cast this);
|
||||
obj.update(this.timeState);
|
||||
if (obj.useInstancing) {
|
||||
this.instanceManager.addObject(obj);
|
||||
} else
|
||||
this.scene.addChild(obj);
|
||||
for (collider in obj.colliders) {
|
||||
if (collider != null)
|
||||
this.collisionWorld.addEntity(collider);
|
||||
}
|
||||
if (obj.isBoundingBoxCollideable)
|
||||
this.collisionWorld.addEntity(obj.boundingCollider);
|
||||
obj.init(cast this, () -> {
|
||||
obj.update(this.timeState);
|
||||
if (obj.useInstancing) {
|
||||
this.instanceManager.addObject(obj);
|
||||
} else
|
||||
this.scene.addChild(obj);
|
||||
for (collider in obj.colliders) {
|
||||
if (collider != null)
|
||||
this.collisionWorld.addEntity(collider);
|
||||
}
|
||||
if (obj.isBoundingBoxCollideable)
|
||||
this.collisionWorld.addEntity(obj.boundingCollider);
|
||||
|
||||
onFinish();
|
||||
});
|
||||
}
|
||||
|
||||
public function addMarble(marble:Marble) {
|
||||
public function addMarble(marble:Marble, onFinish:Void->Void) {
|
||||
this.marbles.push(marble);
|
||||
marble.level = cast this;
|
||||
if (marble.controllable) {
|
||||
marble.init(cast this);
|
||||
this.scene.addChild(marble.camera);
|
||||
this.marble = marble;
|
||||
// Ugly hack
|
||||
// sky.follow = marble;
|
||||
sky.follow = marble.camera;
|
||||
marble.init(cast this, () -> {
|
||||
this.scene.addChild(marble.camera);
|
||||
this.marble = marble;
|
||||
// Ugly hack
|
||||
// sky.follow = marble;
|
||||
sky.follow = marble.camera;
|
||||
this.collisionWorld.addMovingEntity(marble.collider);
|
||||
this.scene.addChild(marble);
|
||||
onFinish();
|
||||
});
|
||||
} else {
|
||||
this.collisionWorld.addMovingEntity(marble.collider);
|
||||
this.scene.addChild(marble);
|
||||
}
|
||||
this.collisionWorld.addMovingEntity(marble.collider);
|
||||
this.scene.addChild(marble);
|
||||
}
|
||||
|
||||
public function update(dt:Float) {
|
||||
|
|
@ -766,10 +849,10 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
function asyncLoadResources() {
|
||||
if (this.resourceLoadFuncs.length != 0) {
|
||||
// if (lock)
|
||||
// return;
|
||||
if (lock)
|
||||
return;
|
||||
|
||||
var func = this.resourceLoadFuncs.pop();
|
||||
var func = this.resourceLoadFuncs.shift();
|
||||
lock = true;
|
||||
#if hl
|
||||
func();
|
||||
|
|
@ -778,12 +861,11 @@ class MarbleWorld extends Scheduler {
|
|||
this.loadingGui.setProgress((1 - resourceLoadFuncs.length / _loadingLength));
|
||||
#end
|
||||
#if js
|
||||
var prom = new js.lib.Promise((resolve, reject) -> {
|
||||
func();
|
||||
func(() -> {
|
||||
lock = false;
|
||||
resolve(true);
|
||||
this.loadingGui.setProgress((1 - resourceLoadFuncs.length / _loadingLength));
|
||||
this._resourcesLoaded++;
|
||||
js.Browser.console.log('${func} is done');
|
||||
});
|
||||
#end
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ class Mission {
|
|||
|
||||
var imageResources:Array<Resource<Image>> = [];
|
||||
|
||||
var imgFileEntry:hxd.fs.FileEntry;
|
||||
|
||||
static var doingLoadPreviewTimeout = false;
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function load() {
|
||||
|
|
@ -63,22 +67,30 @@ class Mission {
|
|||
return mission;
|
||||
}
|
||||
|
||||
public function getPreviewImage() {
|
||||
public function getPreviewImage(onLoaded:h2d.Tile->Void) {
|
||||
if (!this.isClaMission) {
|
||||
var basename = haxe.io.Path.withoutExtension(this.path);
|
||||
if (ResourceLoader.fileSystem.exists(basename + ".png")) {
|
||||
return ResourceLoader.getResource(basename + ".png", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
imgFileEntry = ResourceLoader.fileSystem.get(basename + ".png");
|
||||
imgFileEntry.load(() -> {
|
||||
var ret = ResourceLoader.getResource(basename + ".png", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
onLoaded(ret);
|
||||
});
|
||||
}
|
||||
if (ResourceLoader.fileSystem.exists(basename + ".jpg")) {
|
||||
return ResourceLoader.getResource(basename + ".jpg", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
imgFileEntry = ResourceLoader.fileSystem.get(basename + ".jpg");
|
||||
imgFileEntry.load(() -> {
|
||||
var ret = ResourceLoader.getResource(basename + ".jpg", ResourceLoader.getImage, this.imageResources).toTile();
|
||||
onLoaded(ret);
|
||||
});
|
||||
}
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
return Tile.fromBitmap(img);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
} else {
|
||||
var img = new BitmapData(1, 1);
|
||||
img.setPixel(0, 0, 0);
|
||||
return Tile.fromBitmap(img);
|
||||
onLoaded(Tile.fromBitmap(img));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,33 +60,34 @@ class PathedInterior extends InteriorObject {
|
|||
|
||||
var soundChannel:Channel;
|
||||
|
||||
public static function createFromSimGroup(simGroup:MissionElementSimGroup, level:MarbleWorld) {
|
||||
public static function createFromSimGroup(simGroup:MissionElementSimGroup, level:MarbleWorld, onFinish:PathedInterior->Void) {
|
||||
var interiorElement:MissionElementPathedInterior = cast simGroup.elements.filter((element) -> element._type == MissionElementType.PathedInterior)[0];
|
||||
var difFile = level.mission.getDifPath(interiorElement.interiorresource);
|
||||
if (difFile == null)
|
||||
return null;
|
||||
onFinish(null);
|
||||
var pathedInterior = new PathedInterior();
|
||||
pathedInterior.level = level;
|
||||
|
||||
DifBuilder.loadDif(difFile, pathedInterior, cast MisParser.parseNumber(interiorElement.interiorindex)); // (difFile, path, level, );
|
||||
DifBuilder.loadDif(difFile, pathedInterior, () -> {
|
||||
pathedInterior.identifier = difFile + interiorElement.interiorindex;
|
||||
|
||||
pathedInterior.identifier = difFile + interiorElement.interiorindex;
|
||||
|
||||
pathedInterior.simGroup = simGroup;
|
||||
pathedInterior.element = interiorElement;
|
||||
level.interiors.push(pathedInterior);
|
||||
// await
|
||||
// Util.wait(10); // See shapes for the meaning of this hack
|
||||
// await
|
||||
pathedInterior.init(level);
|
||||
return pathedInterior;
|
||||
pathedInterior.simGroup = simGroup;
|
||||
pathedInterior.element = interiorElement;
|
||||
level.interiors.push(pathedInterior);
|
||||
// await
|
||||
// Util.wait(10); // See shapes for the meaning of this hack
|
||||
// await
|
||||
pathedInterior.init(level, () -> {
|
||||
onFinish(pathedInterior);
|
||||
});
|
||||
}, cast MisParser.parseNumber(interiorElement.interiorindex));
|
||||
}
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld) {
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
this.basePosition = MisParser.parseVector3(this.element.baseposition);
|
||||
this.basePosition.x = -this.basePosition.x;
|
||||
this.baseOrientation = MisParser.parseRotation(this.element.baserotation);
|
||||
|
|
@ -132,11 +133,14 @@ class PathedInterior extends InteriorObject {
|
|||
}
|
||||
|
||||
if (this.element.datablock.toLowerCase() == "pathedmovingblock") {
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/movingblockloop.wav", ResourceLoader.getAudio,
|
||||
this.soundResources), new Vector(), true);
|
||||
ResourceLoader.loader.load("sound/movingblockloop.wav").entry.load(() -> {
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/movingblockloop.wav", ResourceLoader.getAudio,
|
||||
this.soundResources), new Vector(), true);
|
||||
});
|
||||
}
|
||||
|
||||
this.reset();
|
||||
onFinish();
|
||||
}
|
||||
|
||||
public function update(timeState:TimeState) {
|
||||
|
|
|
|||
134
src/Sky.hx
134
src/Sky.hx
|
|
@ -15,6 +15,7 @@ import src.ResourceLoader;
|
|||
import h3d.scene.Object;
|
||||
import src.Resource;
|
||||
import hxd.res.Image;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class Sky extends Object {
|
||||
public var dmlPath:String;
|
||||
|
|
@ -25,31 +26,33 @@ class Sky extends Object {
|
|||
super();
|
||||
}
|
||||
|
||||
public function init(level:MarbleWorld) {
|
||||
var texture = createSkyboxCubeTextured(this.dmlPath);
|
||||
var sky = new h3d.prim.Sphere(1, 128, 128);
|
||||
sky.addNormals();
|
||||
sky.addUVs();
|
||||
var skyMesh = new h3d.scene.Mesh(sky, this);
|
||||
skyMesh.material.mainPass.culling = Front;
|
||||
// This is such a hack
|
||||
// skyMesh.material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
|
||||
skyMesh.material.mainPass.enableLights = false;
|
||||
skyMesh.material.shadows = false;
|
||||
skyMesh.material.blendMode = None;
|
||||
// var pbrprops = skyMesh.material.mainPass.getShader(PropsValues);
|
||||
// pbrprops.emissiveValue = 1;
|
||||
// pbrprops.roughnessValue = 0;`
|
||||
// pbrprops.occlusionValue = 0;
|
||||
// pbrprops.metalnessValue = 1;
|
||||
public function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
createSkyboxCubeTextured(this.dmlPath, texture -> {
|
||||
var sky = new h3d.prim.Sphere(1, 128, 128);
|
||||
sky.addNormals();
|
||||
sky.addUVs();
|
||||
var skyMesh = new h3d.scene.Mesh(sky, this);
|
||||
skyMesh.material.mainPass.culling = Front;
|
||||
// This is such a hack
|
||||
// skyMesh.material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
|
||||
skyMesh.material.mainPass.enableLights = false;
|
||||
skyMesh.material.shadows = false;
|
||||
skyMesh.material.blendMode = None;
|
||||
// var pbrprops = skyMesh.material.mainPass.getShader(PropsValues);
|
||||
// pbrprops.emissiveValue = 1;
|
||||
// pbrprops.roughnessValue = 0;`
|
||||
// pbrprops.occlusionValue = 0;
|
||||
// pbrprops.metalnessValue = 1;
|
||||
|
||||
skyMesh.scale(3500);
|
||||
// var env = new Environment(texture);
|
||||
// env.compute();
|
||||
// var renderer = cast(level.scene.renderer, h3d.scene.pbr.Renderer);
|
||||
var shad = new Skybox(texture);
|
||||
skyMesh.material.mainPass.addShader(shad);
|
||||
skyMesh.material.mainPass.depthWrite = false;
|
||||
skyMesh.scale(3500);
|
||||
// var env = new Environment(texture);
|
||||
// env.compute();
|
||||
// var renderer = cast(level.scene.renderer, h3d.scene.pbr.Renderer);
|
||||
var shad = new Skybox(texture);
|
||||
skyMesh.material.mainPass.addShader(shad);
|
||||
skyMesh.material.mainPass.depthWrite = false;
|
||||
onFinish();
|
||||
});
|
||||
// skyMesh.material.shadows = false;
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +62,7 @@ class Sky extends Object {
|
|||
}
|
||||
}
|
||||
|
||||
function createSkyboxCubeTextured(dmlPath:String) {
|
||||
function createSkyboxCubeTextured(dmlPath:String, onFinish:Texture->Void) {
|
||||
#if (js || android)
|
||||
dmlPath = StringTools.replace(dmlPath, "data/", "");
|
||||
#end
|
||||
|
|
@ -73,46 +76,63 @@ class Sky extends Object {
|
|||
// 0: front
|
||||
var skyboxIndices = [3, 1, 2, 0, 4, 5];
|
||||
|
||||
var filestoload = [];
|
||||
for (i in 0...6) {
|
||||
var line = StringTools.trim(lines[i]);
|
||||
var filenames = ResourceLoader.getFullNamesOf(dmlDirectory + '/' + line);
|
||||
if (filenames.length == 0) {
|
||||
var pixels = Texture.fromColor(0).capturePixels(0, 0);
|
||||
skyboxImages.push(pixels);
|
||||
// var tex = new h3d.mat.Texture();
|
||||
// skyboxImages.push(new BitmapData(128, 128));
|
||||
} else {
|
||||
var image = ResourceLoader.getResource(filenames[0], ResourceLoader.getImage, this.imageResources).toBitmap();
|
||||
var pixels = image.getPixels();
|
||||
skyboxImages.push(pixels);
|
||||
if (filenames.length != 0) {
|
||||
filestoload.push(filenames[0]);
|
||||
}
|
||||
}
|
||||
var maxwidth = 0;
|
||||
var maxheight = 0;
|
||||
for (texture in skyboxImages) {
|
||||
if (texture.height > maxheight)
|
||||
maxheight = texture.height;
|
||||
if (texture.width > maxwidth)
|
||||
maxwidth = texture.width;
|
||||
}
|
||||
|
||||
Util.flipImage(skyboxImages[0], true, false);
|
||||
Util.flipImage(skyboxImages[4], true, false);
|
||||
Util.rotateImage(skyboxImages[5], Math.PI);
|
||||
Util.flipImage(skyboxImages[5], true, false);
|
||||
Util.rotateImage(skyboxImages[1], -Math.PI / 2);
|
||||
Util.flipImage(skyboxImages[1], true, false);
|
||||
Util.rotateImage(skyboxImages[2], Math.PI);
|
||||
Util.flipImage(skyboxImages[2], true, false);
|
||||
Util.rotateImage(skyboxImages[3], Math.PI / 2);
|
||||
Util.flipImage(skyboxImages[3], true, false);
|
||||
var worker = new ResourceLoaderWorker(() -> {
|
||||
for (i in 0...6) {
|
||||
var line = StringTools.trim(lines[i]);
|
||||
var filenames = ResourceLoader.getFullNamesOf(dmlDirectory + '/' + line);
|
||||
if (filenames.length == 0) {
|
||||
var pixels = Texture.fromColor(0).capturePixels(0, 0);
|
||||
skyboxImages.push(pixels);
|
||||
// var tex = new h3d.mat.Texture();
|
||||
// skyboxImages.push(new BitmapData(128, 128));
|
||||
} else {
|
||||
var image = ResourceLoader.getResource(filenames[0], ResourceLoader.getImage, this.imageResources).toBitmap();
|
||||
var pixels = image.getPixels();
|
||||
skyboxImages.push(pixels);
|
||||
}
|
||||
}
|
||||
var maxwidth = 0;
|
||||
var maxheight = 0;
|
||||
for (texture in skyboxImages) {
|
||||
if (texture.height > maxheight)
|
||||
maxheight = texture.height;
|
||||
if (texture.width > maxwidth)
|
||||
maxwidth = texture.width;
|
||||
}
|
||||
|
||||
var cubemaptexture = new Texture(maxheight, maxwidth, [Cube]);
|
||||
for (i in 0...6) {
|
||||
cubemaptexture.uploadPixels(skyboxImages[skyboxIndices[i]], 0, i);
|
||||
Util.flipImage(skyboxImages[0], true, false);
|
||||
Util.flipImage(skyboxImages[4], true, false);
|
||||
Util.rotateImage(skyboxImages[5], Math.PI);
|
||||
Util.flipImage(skyboxImages[5], true, false);
|
||||
Util.rotateImage(skyboxImages[1], -Math.PI / 2);
|
||||
Util.flipImage(skyboxImages[1], true, false);
|
||||
Util.rotateImage(skyboxImages[2], Math.PI);
|
||||
Util.flipImage(skyboxImages[2], true, false);
|
||||
Util.rotateImage(skyboxImages[3], Math.PI / 2);
|
||||
Util.flipImage(skyboxImages[3], true, false);
|
||||
|
||||
var cubemaptexture = new Texture(maxheight, maxwidth, [Cube]);
|
||||
for (i in 0...6) {
|
||||
cubemaptexture.uploadPixels(skyboxImages[skyboxIndices[i]], 0, i);
|
||||
}
|
||||
onFinish(cubemaptexture);
|
||||
});
|
||||
|
||||
for (file in filestoload) {
|
||||
worker.loadFile(file);
|
||||
}
|
||||
return cubemaptexture;
|
||||
worker.run();
|
||||
} else {
|
||||
onFinish(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class ManifestEntry extends FileEntry {
|
|||
private var bytes:Bytes;
|
||||
private var readPos:Int;
|
||||
private var loaded:Bool;
|
||||
private var loadPromise:js.lib.Promise<Void>;
|
||||
#end
|
||||
|
||||
public function new(fs:ManifestFileSystem, name:String, relPath:String, file:String, ?originalFile:String) {
|
||||
|
|
@ -130,7 +131,7 @@ class ManifestEntry extends FileEntry {
|
|||
if (onReady != null)
|
||||
haxe.Timer.delay(onReady, 1);
|
||||
} else {
|
||||
js.Browser.window.fetch(file).then((res:js.html.Response) -> {
|
||||
this.loadPromise = js.Browser.window.fetch(file).then((res:js.html.Response) -> {
|
||||
return res.arrayBuffer();
|
||||
}).then((buf:js.lib.ArrayBuffer) -> {
|
||||
loaded = true;
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ class HelpCreditsGui extends GuiImage {
|
|||
dtsObj.matNameOverride.set(key, value);
|
||||
}
|
||||
}
|
||||
dtsObj.init(null);
|
||||
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
|
||||
for (mat in dtsObj.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
if (mat.blendMode != Alpha && mat.blendMode != Add)
|
||||
|
|
|
|||
|
|
@ -264,21 +264,22 @@ class PlayGui {
|
|||
// gemImageObject.matNameOverride.set("base.gem", "base.gem.");
|
||||
gemImageObject.ambientSpinFactor /= -2;
|
||||
// ["base.gem"] = color + ".gem";
|
||||
gemImageObject.init(null);
|
||||
for (mat in gemImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
gemImageObject.init(null, () -> {
|
||||
for (mat in gemImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
|
||||
// Huge hacks
|
||||
if (mat.blendMode != Add) {
|
||||
var alphaShader = new h3d.shader.AlphaChannel();
|
||||
mat.mainPass.addShader(alphaShader);
|
||||
// Huge hacks
|
||||
if (mat.blendMode != Add) {
|
||||
var alphaShader = new h3d.shader.AlphaChannel();
|
||||
mat.mainPass.addShader(alphaShader);
|
||||
}
|
||||
}
|
||||
}
|
||||
gemImageScene.addChild(gemImageObject);
|
||||
var gemImageCenter = gemImageObject.getBounds().getCenter();
|
||||
gemImageScene.addChild(gemImageObject);
|
||||
var gemImageCenter = gemImageObject.getBounds().getCenter();
|
||||
|
||||
gemImageScene.camera.pos = new Vector(0, 3, gemImageCenter.z);
|
||||
gemImageScene.camera.target = new Vector(gemImageCenter.x, gemImageCenter.y, gemImageCenter.z);
|
||||
gemImageScene.camera.pos = new Vector(0, 3, gemImageCenter.z);
|
||||
gemImageScene.camera.target = new Vector(gemImageCenter.x, gemImageCenter.y, gemImageCenter.z);
|
||||
});
|
||||
}
|
||||
|
||||
function initPowerupBox() {
|
||||
|
|
@ -416,17 +417,18 @@ class PlayGui {
|
|||
powerupImageObject.ambientRotate = true;
|
||||
powerupImageObject.ambientSpinFactor /= 2;
|
||||
powerupImageObject.showSequences = false;
|
||||
powerupImageObject.init(null);
|
||||
for (mat in powerupImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
if (mat.blendMode != Alpha && mat.blendMode != Add)
|
||||
mat.mainPass.addShader(new h3d.shader.AlphaChannel());
|
||||
}
|
||||
powerupImageScene.addChild(powerupImageObject);
|
||||
var powerupImageCenter = powerupImageObject.getBounds().getCenter();
|
||||
powerupImageObject.init(null, () -> {
|
||||
for (mat in powerupImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
if (mat.blendMode != Alpha && mat.blendMode != Add)
|
||||
mat.mainPass.addShader(new h3d.shader.AlphaChannel());
|
||||
}
|
||||
powerupImageScene.addChild(powerupImageObject);
|
||||
var powerupImageCenter = powerupImageObject.getBounds().getCenter();
|
||||
|
||||
powerupImageScene.camera.pos = new Vector(0, 4, powerupImageCenter.z);
|
||||
powerupImageScene.camera.target = new Vector(powerupImageCenter.x, powerupImageCenter.y, powerupImageCenter.z);
|
||||
powerupImageScene.camera.pos = new Vector(0, 4, powerupImageCenter.z);
|
||||
powerupImageScene.camera.target = new Vector(powerupImageCenter.x, powerupImageCenter.y, powerupImageCenter.z);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package gui;
|
||||
|
||||
import haxe.ds.Option;
|
||||
import hxd.Key;
|
||||
import gui.GuiControl.MouseState;
|
||||
import h3d.Matrix;
|
||||
|
|
@ -35,6 +36,10 @@ class PlayMissionGui extends GuiImage {
|
|||
var buttonCooldown:Float = 0.5;
|
||||
var maxButtonCooldown:Float = 0.5;
|
||||
|
||||
#if js
|
||||
var previewTimeoutHandle:Option<Int> = None;
|
||||
#end
|
||||
|
||||
public function new() {
|
||||
MissionList.buildMissionList();
|
||||
|
||||
|
|
@ -112,8 +117,11 @@ class PlayMissionGui extends GuiImage {
|
|||
textWnd.extent = new Vector(276, 229);
|
||||
pmBox.addChild(textWnd);
|
||||
|
||||
var pmPreview = new GuiImage(ResourceLoader.getResource("data/missions/beginner/superspeed.jpg", ResourceLoader.getImage, this.imageResources)
|
||||
.toTile());
|
||||
var temprev = new BitmapData(1, 1);
|
||||
temprev.setPixel(0, 0, 0);
|
||||
var tmpprevtile = Tile.fromBitmap(temprev);
|
||||
|
||||
var pmPreview = new GuiImage(tmpprevtile);
|
||||
pmPreview.position = new Vector(312, 42);
|
||||
pmPreview.extent = new Vector(258, 193);
|
||||
pmBox.addChild(pmPreview);
|
||||
|
|
@ -465,9 +473,27 @@ class PlayMissionGui extends GuiImage {
|
|||
pmDescriptionOther.text.text = descText2;
|
||||
pmDescriptionOther.text.loadImage = (name) -> goldBadge;
|
||||
|
||||
pmPreview.bmp.tile = currentMission.getPreviewImage();
|
||||
pmPreview.bmp.tile = tmpprevtile;
|
||||
#if js
|
||||
switch (previewTimeoutHandle) {
|
||||
case None:
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
}, 75));
|
||||
case Some(previewTimeoutHandle_id):
|
||||
js.Browser.window.clearTimeout(previewTimeoutHandle_id);
|
||||
previewTimeoutHandle = Some(js.Browser.window.setTimeout(() -> {
|
||||
currentMission.getPreviewImage(prevImg -> {
|
||||
pmPreview.bmp.tile = prevImg;
|
||||
});
|
||||
}, 75));
|
||||
}
|
||||
#end
|
||||
|
||||
levelBkgnd.text.text = currentCategory.charAt(0).toUpperCase() + currentCategory.substr(1) + ' Level ${currentSelection + 1}';
|
||||
|
||||
levelFgnd.text.text = currentCategory.charAt(0).toUpperCase() + currentCategory.substr(1) + ' Level ${currentSelection + 1}';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import mis.MissionElement.MissionElementItem;
|
|||
import src.TimeState;
|
||||
import h3d.Vector;
|
||||
import src.DtsObject;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class AntiGravity extends PowerUp {
|
||||
public function new(element:MissionElementItem) {
|
||||
|
|
@ -15,7 +16,6 @@ class AntiGravity extends PowerUp {
|
|||
this.identifier = "AntiGravity";
|
||||
this.pickUpName = "Gravity Modifier";
|
||||
this.autoUse = true;
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/gravitychange.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
@ -34,4 +34,13 @@ class AntiGravity extends PowerUp {
|
|||
// this.level.particles.createEmitter(superJumpParticleOptions, null, () => Util.vecOimoToThree(marble.body.getPosition()));
|
||||
// this.level.deselectPowerUp();
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/gravitychange.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/gravitychange.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,14 @@ class DuctFan extends ForceObject {
|
|||
];
|
||||
}
|
||||
|
||||
public override function init(level:src.MarbleWorld) {
|
||||
super.init(level);
|
||||
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/fan_loop.wav", ResourceLoader.getAudio, this.soundResources),
|
||||
new Vector(1e8, 1e8, 1e8), true);
|
||||
public override function init(level:src.MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/fan_loop.wav").entry.load(() -> {
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/fan_loop.wav", ResourceLoader.getAudio,
|
||||
this.soundResources), new Vector(1e8, 1e8, 1e8), true);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override function update(timeState:src.TimeState) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@ class EndPad extends DtsObject {
|
|||
this.identifier = "EndPad";
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/firewrks.wav").entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
// override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
||||
// if (!isEntered) {
|
||||
// isEntered = true;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import src.MarbleWorld;
|
|||
import mis.MissionElement.MissionElementItem;
|
||||
import src.TimeState;
|
||||
import src.DtsObject;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class Gem extends DtsObject {
|
||||
public var pickedUp:Bool;
|
||||
|
|
@ -26,6 +27,15 @@ class Gem extends DtsObject {
|
|||
this.matNameOverride.set('base.gem', color + ".gem");
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
var worker = new ResourceLoaderWorker(onFinish);
|
||||
worker.loadFile('sound/gotgem.wav');
|
||||
worker.loadFile('sound/gotallgems.wav');
|
||||
worker.run();
|
||||
});
|
||||
}
|
||||
|
||||
public override function setHide(hide:Bool) {
|
||||
if (hide) {
|
||||
this.pickedUp = true;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import mis.MissionElement.MissionElementItem;
|
|||
import src.TimeState;
|
||||
import src.DtsObject;
|
||||
import src.AudioManager;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class Helicopter extends PowerUp {
|
||||
public function new(element:MissionElementItem) {
|
||||
|
|
@ -15,7 +16,15 @@ class Helicopter extends PowerUp {
|
|||
this.showSequences = false;
|
||||
this.identifier = "Helicopter";
|
||||
this.pickUpName = "Gyrocopter PowerUp";
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pugyrocoptervoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/pugyrocoptervoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pugyrocoptervoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import src.ParticleSystem.ParticleEmitterOptions;
|
|||
import src.ParticleSystem.ParticleData;
|
||||
import h3d.Vector;
|
||||
import src.ResourceLoader;
|
||||
import src.MarbleWorld;
|
||||
|
||||
final landMineParticle:ParticleEmitterOptions = {
|
||||
ejectionPeriod: 2,
|
||||
|
|
@ -114,6 +115,12 @@ class LandMine extends DtsObject {
|
|||
landMineSparkParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/explode1.wav").entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
override function onMarbleContact(timeState:TimeState, ?contact:CollisionInfo) {
|
||||
if (this.isCollideable) {
|
||||
// marble.velocity = marble.velocity.add(vec);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import src.ResourceLoader;
|
|||
import mis.MissionElement.MissionElementItem;
|
||||
import src.TimeState;
|
||||
import src.DtsObject;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class ShockAbsorber extends PowerUp {
|
||||
public function new(element:MissionElementItem) {
|
||||
|
|
@ -13,7 +14,15 @@ class ShockAbsorber extends PowerUp {
|
|||
this.isTSStatic = false;
|
||||
this.identifier = "ShockAbsorber";
|
||||
this.pickUpName = "Shock Absorber PowerUp";
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pushockabsorbervoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/pushockabsorbervoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pushockabsorbervoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
|
|||
|
|
@ -28,11 +28,14 @@ class SmallDuctFan extends ForceObject {
|
|||
];
|
||||
}
|
||||
|
||||
public override function init(level:src.MarbleWorld) {
|
||||
super.init(level);
|
||||
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/fan_loop.wav", ResourceLoader.getAudio, this.soundResources),
|
||||
new Vector(1e8, 1e8, 1e8), true);
|
||||
public override function init(level:src.MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/fan_loop.wav").entry.load(() -> {
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/fan_loop.wav", ResourceLoader.getAudio,
|
||||
this.soundResources), new Vector(1e8, 1e8, 1e8), true);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override function update(timeState:src.TimeState) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import src.ResourceLoader;
|
|||
import mis.MissionElement.MissionElementItem;
|
||||
import src.TimeState;
|
||||
import src.DtsObject;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class SuperBounce extends PowerUp {
|
||||
public function new(element:MissionElementItem) {
|
||||
|
|
@ -13,13 +14,21 @@ class SuperBounce extends PowerUp {
|
|||
this.isTSStatic = false;
|
||||
this.identifier = "SuperBounce";
|
||||
this.pickUpName = "Super Bounce PowerUp";
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperbouncevoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
return this.level.pickUpPowerUp(this);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/pusuperbouncevoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperbouncevoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function use(timeState:TimeState) {
|
||||
var marble = this.level.marble;
|
||||
marble.enableSuperBounce(timeState.currentAttemptTime);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import src.ParticleSystem.ParticleData;
|
|||
import h3d.Vector;
|
||||
import src.AudioManager;
|
||||
import src.DtsObject;
|
||||
import src.MarbleWorld;
|
||||
|
||||
final superJumpParticleOptions:src.ParticleSystem.ParticleEmitterOptions = {
|
||||
ejectionPeriod: 10,
|
||||
|
|
@ -45,7 +46,15 @@ class SuperJump extends PowerUp {
|
|||
sjEmitterParticleData = new ParticleData();
|
||||
sjEmitterParticleData.identifier = "superJumpParticle";
|
||||
sjEmitterParticleData.texture = ResourceLoader.getResource("data/particles/twirl.png", ResourceLoader.getTexture, this.textureResources);
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperjumpvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/pusuperjumpvoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("sound/pusuperjumpvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
ResourceLoader.loader.load("sound/dosuperjump.wav").entry.load(onFinish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import h3d.Quat;
|
|||
import h3d.Vector;
|
||||
import src.DtsObject;
|
||||
import src.AudioManager;
|
||||
import src.MarbleWorld;
|
||||
|
||||
final superSpeedParticleOptions:ParticleEmitterOptions = {
|
||||
ejectionPeriod: 5,
|
||||
|
|
@ -51,7 +52,15 @@ class SuperSpeed extends PowerUp {
|
|||
ssEmitterParticleData = new ParticleData();
|
||||
ssEmitterParticleData.identifier = "superSpeedParticle";
|
||||
ssEmitterParticleData.texture = ResourceLoader.getResource("data/particles/spark.png", ResourceLoader.getTexture, this.textureResources);
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperspeedvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/pusuperspeedvoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/pusuperspeedvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
ResourceLoader.loader.load("sound/dosuperspeed.wav").entry.load(onFinish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import src.ResourceLoader;
|
|||
import mis.MissionElement.MissionElementItem;
|
||||
import src.TimeState;
|
||||
import mis.MisParser;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class TimeTravel extends PowerUp {
|
||||
var timeBonus:Float = 5;
|
||||
|
|
@ -23,7 +24,15 @@ class TimeTravel extends PowerUp {
|
|||
this.cooldownDuration = 1e8;
|
||||
this.useInstancing = true;
|
||||
this.autoUse = true;
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/putimetravelvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/putimetravelvoice.wav").entry.load(() -> {
|
||||
this.pickupSound = ResourceLoader.getResource("data/sound/putimetravelvoice.wav", ResourceLoader.getAudio, this.soundResources);
|
||||
ResourceLoader.loader.load("sound/timetravelactive.wav").entry.load(onFinish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function pickUp():Bool {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import h3d.Vector;
|
|||
import src.ForceObject;
|
||||
import src.ResourceLoader;
|
||||
import src.AudioManager;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class Tornado extends ForceObject {
|
||||
var soundChannel:Channel;
|
||||
|
|
@ -44,14 +45,18 @@ class Tornado extends ForceObject {
|
|||
];
|
||||
}
|
||||
|
||||
public override function init(level:src.MarbleWorld) {
|
||||
super.init(level);
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/tornado.wav", ResourceLoader.getAudio, this.soundResources),
|
||||
new Vector(1e8, 1e8, 1e8), true);
|
||||
for (material in this.materials) {
|
||||
material.blendMode = Alpha;
|
||||
// material.mainPass.culling = h3d.mat.Data.Face.None;
|
||||
}
|
||||
public override function init(level:src.MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/tornado.wav").entry.load(() -> {
|
||||
this.soundChannel = AudioManager.playSound(ResourceLoader.getResource("data/sound/tornado.wav", ResourceLoader.getAudio, this.soundResources),
|
||||
new Vector(1e8, 1e8, 1e8), true);
|
||||
for (material in this.materials) {
|
||||
material.blendMode = Alpha;
|
||||
// material.mainPass.culling = h3d.mat.Data.Face.None;
|
||||
}
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public override function update(timeState:src.TimeState) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import h3d.Vector;
|
|||
import src.ForceObject;
|
||||
import src.ResourceLoader;
|
||||
import src.AudioManager;
|
||||
import src.MarbleWorld;
|
||||
|
||||
class Trapdoor extends DtsObject {
|
||||
var lastContactTime = -1e8;
|
||||
|
|
@ -25,6 +26,12 @@ class Trapdoor extends DtsObject {
|
|||
this.hasNonVisualSequences = true;
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
super.init(level, () -> {
|
||||
ResourceLoader.loader.load("sound/trapdooropen.wav").entry.load(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
public override function update(timeState:TimeState) {
|
||||
var currentCompletion = this.getCurrentCompletion(timeState);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,4 +10,8 @@ class HelpTrigger extends Trigger {
|
|||
this.level.displayHelp(this.element.text);
|
||||
// this.level.replay.recordMarbleEnter(this);
|
||||
}
|
||||
|
||||
public override function init(onFinish:Void->Void) {
|
||||
ResourceLoader.loader.load("sound/infotutorial.wav").entry.load(onFinish);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
package triggers;
|
||||
|
||||
import src.TimeState;
|
||||
import src.ResourceLoader;
|
||||
|
||||
class InBoundsTrigger extends Trigger {
|
||||
override function onMarbleLeave(timeState:TimeState) {
|
||||
this.level.goOutOfBounds();
|
||||
// this.level.replay.recordMarbleLeave(this);
|
||||
}
|
||||
|
||||
public override function init(onFinish:Void->Void) {
|
||||
ResourceLoader.loader.load("sound/whoosh.wav").entry.load(onFinish);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
package triggers;
|
||||
|
||||
import src.TimeState;
|
||||
import src.ResourceLoader;
|
||||
|
||||
class OutOfBoundsTrigger extends Trigger {
|
||||
override function onMarbleInside(time:TimeState) {
|
||||
this.level.goOutOfBounds();
|
||||
// this.level.replay.recordMarbleInside(this);
|
||||
}
|
||||
|
||||
public override function init(onFinish:Void->Void) {
|
||||
ResourceLoader.loader.load("sound/whoosh.wav").entry.load(onFinish);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,4 +73,8 @@ class Trigger extends GameObject {
|
|||
// // m2.setPosition(boundingbox.xMax, boundingbox.yMax, boundingbox.zMax);
|
||||
// mesh.setPosition(boundingbox.xMin, boundingbox.yMin, boundingbox.zMin);
|
||||
}
|
||||
|
||||
public function init(onFinish:Void->Void) {
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue