All courses now render properly. WIP items (shell, banana, fake item)
This commit is contained in:
1 parent
e010627b5d
commit
ff21142744
45 files changed
+3400
-1193
No files matched your search
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// tileFlattener.js
|
||||
//--------------------
|
||||
// Renders screens or cells to 2d canvas. Useful for drawing UI elements from the ROM.
|
||||
// by RHY3756547
|
||||
//
|
||||
// includes: main.js
|
||||
//
|
||||
|
||||
window.TileFlattener = function(palette, tiles, map) {
|
||||
|
||||
this.palette = palette;
|
||||
this.tiles = tiles;
|
||||
this.map = map;
|
||||
this.toCanvas = toCanvas;
|
||||
|
||||
this.cellMode = map.cebk != null;
|
||||
|
||||
var tileCache = {};
|
||||
var zero = [0, 0, 0, 0];
|
||||
var emptyTile = new Uint8ClampedArray(64);
|
||||
|
||||
function getTileImg(pal0trans, tile, pal) {
|
||||
var cacheID = tile + ":" + pal;
|
||||
var item = tileCache[cacheID];
|
||||
if (item != null) return item;
|
||||
//make the tile
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = 8;
|
||||
canvas.height = 8;
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
||||
var d = new Uint8ClampedArray(8*8*4);
|
||||
var data = new ImageData(d, 8, 8);
|
||||
var targ = 0;
|
||||
var colors = palette.pltt.palettes[pal] || [];
|
||||
var tileData = tiles.char.tiles[tile] || emptyTile;
|
||||
|
||||
for (var i=0; i<64; i++) {
|
||||
var colID = tileData[i];
|
||||
var col = (pal0trans && colID == 0) ? zero : (colors[colID] || zero);
|
||||
d[targ++] = col[0];
|
||||
d[targ++] = col[1];
|
||||
d[targ++] = col[2];
|
||||
d[targ++] = col[3];
|
||||
}
|
||||
|
||||
ctx.putImageData(data, 0, 0);
|
||||
tileCache[cacheID] = canvas;
|
||||
return canvas;
|
||||
}
|
||||
|
||||
function calcImageSize(image) {
|
||||
var xMin = 65536;
|
||||
var yMin = 65536;
|
||||
var xMax = 0;
|
||||
var yMax = 0;
|
||||
for (var i=0; i<image.cells.length; i++) {
|
||||
var cell = image.cells[i];
|
||||
var size = cell.size;
|
||||
var x = cell.x + size[0];
|
||||
if (x > xMax) xMax = x;
|
||||
x -= size[0];
|
||||
if (x < xMin) xMin = x;
|
||||
var y = cell.y + size[1];
|
||||
if (y > yMax) yMax = y;
|
||||
y -= size[1];
|
||||
if (y < yMin) yMin = y;
|
||||
}
|
||||
return [xMin, yMin, xMax, yMax];
|
||||
}
|
||||
|
||||
function toCanvas(pal0trans, imageInd, palInd) {
|
||||
var canvas = document.createElement("canvas");
|
||||
if (this.cellMode) {
|
||||
//essentially a collection of ds sprites
|
||||
//render out the image the user has requested
|
||||
var image = map.cebk.images[imageInd];
|
||||
var isize = calcImageSize(image);
|
||||
|
||||
canvas.width = isize[2] - isize[0];
|
||||
canvas.height = isize[3] - isize[1];
|
||||
var ctx = canvas.getContext("2d");
|
||||
var tileWidth = this.tiles.char.tilesX;
|
||||
image.cells.sort(function(a, b){return b.priority - a.priority});
|
||||
|
||||
for (var i=image.cells.length-1; i>=0; i--) {
|
||||
var cell = image.cells[i];
|
||||
|
||||
var size = cell.size;
|
||||
var sx2 = size[0]/2;
|
||||
var sy2 = size[1]/2;
|
||||
ctx.save();
|
||||
ctx.translate(cell.x + sx2 - isize[0], cell.y + sy2 - isize[1]);
|
||||
ctx.scale(cell.xFlip?(-1):1, cell.yFlip?(-1):1);
|
||||
|
||||
var tile = cell.tileOffset;
|
||||
var pal = cell.pal;
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeWidth = 1;
|
||||
if (cell.disable) continue;
|
||||
|
||||
//draw oam sprite
|
||||
var base = tile;
|
||||
for (var y=0; y<size[1]; y+=8) {
|
||||
for (var x=0; x<size[0]; x+=8) {
|
||||
var img = getTileImg(pal0trans, tile++, pal);
|
||||
ctx.drawImage(img, x-sx2, y-sy2);
|
||||
}
|
||||
if (tileWidth != 65535) { //when defined, wrap to the next row when drawing a lower portion of the sprite
|
||||
base += tileWidth;
|
||||
tile = base;
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
} else {
|
||||
//screen render, very simple
|
||||
var screen = map.scrn;
|
||||
canvas.width = screen.screenWidth;
|
||||
canvas.height = screen.screenHeight;
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
||||
var data = screen.data;
|
||||
var tileWidth = (screen.screenWidth / 8);
|
||||
var tileHeight = (screen.screenHeight / 8);
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
for (var i=0; i<data.length; i++) {
|
||||
var info = data[i];
|
||||
|
||||
/*
|
||||
Format is (YYYYXXNNNNNNNNNN)
|
||||
Y4 Palette Number
|
||||
X2 Transformation (YFlip/XFlip)
|
||||
N10 Tile Number
|
||||
*/
|
||||
var pal = info >> 12;
|
||||
var trans = (info >> 10) & 3;
|
||||
var tile = info & 0x3FF;
|
||||
|
||||
var img = getTileImg(pal0trans, tile, pal);
|
||||
var xf = (trans&1) > 0;
|
||||
var yf = (trans&2) > 0;
|
||||
|
||||
if (xf || yf) {
|
||||
//transform
|
||||
ctx.save();
|
||||
ctx.translate(x + 4, y + 4);
|
||||
ctx.scale(xf?(-1):1, yf?(-1):1);
|
||||
ctx.drawImage(img, -4, -4);
|
||||
ctx.restore();
|
||||
} else {
|
||||
ctx.drawImage(img, x, y);
|
||||
}
|
||||
|
||||
x += 8;
|
||||
if (x >= screen.screenWidth) {
|
||||
x -= screen.screenWidth;
|
||||
y += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
@@ -99,13 +99,15 @@ window.MKDS_COLTYPE = new (function(){
|
||||
this.STICKY = 0x0D; //sets gravity to negative this plane's normal until the object hasn't collided for a few frames.
|
||||
this.SMALLJUMP = 0x0E; //choco island 2's disaster ramps
|
||||
this.CANNON = 0x0F; //activates cannon. basic effect id is the cannon to use.
|
||||
this.UNKNOWN = 0x10; //it is a mystery...
|
||||
this.WALLOOB = 0x10; //like a wall. normally only appears oob, but doesn't seem to have any special behaviour apart from maybe slowing you down more.
|
||||
this.FALLSWATER = 0x11; //points to falls object in nkm, gets motion parameters from there.
|
||||
this.BOOST2 = 0x12;
|
||||
this.LOOP = 0x13; //like sticky but with boost applied. see rainbow road ds
|
||||
this.SOUNDROAD = 0x14;
|
||||
this.RR_SPECIAL_WALL = 0x15;
|
||||
|
||||
this.KNOCKBACK_DAMAGE = 0x1F;
|
||||
|
||||
this.GROUP_ROAD = [
|
||||
this.ROAD, this.OFFROAD1, this.OFFROAD2, this.OFFROAD3, this.OFFROAD4, this.SLIPPERY, this.BOOST,
|
||||
this.JUMP_PAD, this.STICKY, this.SMALLJUMP, this.FALLSWATER, this.BOOST2, this.LOOP, this.SOUNDROAD,
|
||||
@@ -117,17 +119,23 @@ window.MKDS_COLTYPE = new (function(){
|
||||
this.JUMP_PAD, this.STICKY, this.SMALLJUMP, this.FALLSWATER, this.BOOST2, this.LOOP, this.SOUNDROAD,
|
||||
this.OOB, this.OFFROADMAIN,
|
||||
|
||||
this.WALL, this.WALL2, this.RR_SPECIAL_WALL
|
||||
this.WALL, this.WALL2, this.WALLOOB, this.RR_SPECIAL_WALL,
|
||||
|
||||
this.KNOCKBACK_DAMAGE
|
||||
]
|
||||
|
||||
this.GROUP_WALL = [
|
||||
this.WALL, this.WALL2, this.RR_SPECIAL_WALL
|
||||
this.WALL, this.WALL2, this.WALLOOB, this.RR_SPECIAL_WALL, this.KNOCKBACK_DAMAGE
|
||||
]
|
||||
|
||||
this.GROUP_BOOST = [
|
||||
this.BOOST, this.BOOST2, this.LOOP
|
||||
]
|
||||
|
||||
this.GROUP_OOB = [
|
||||
this.OOB, this.FALL
|
||||
]
|
||||
|
||||
this.PHYS_MAP = new Array(31);
|
||||
this.PHYS_MAP[this.ROAD] = 0;
|
||||
this.PHYS_MAP[this.OFFROAD3] = 2;
|
||||
@@ -194,7 +202,7 @@ window.MKDS_COLTYPE = new (function(){
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_GRASS, drive: MKDS_COLSOUNDS.DRIVE_GRASS, particle: 32},
|
||||
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND, particle: 28},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND, particle: 40}, //sky garden cloud
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_SAND, brake: MKDS_COLSOUNDS.BRAKE_SAND, land: MKDS_COLSOUNDS.LAND_SAND, drive: MKDS_COLSOUNDS.DRIVE_SAND, particle: 28},
|
||||
{drift: MKDS_COLSOUNDS.DRIFT_ASPHALT, brake: MKDS_COLSOUNDS.BRAKE, land: MKDS_COLSOUNDS.LAND_SNOW, particle:112}, //snow
|
||||
{},
|
||||
@@ -263,7 +271,7 @@ window.MKDS_COLTYPE = new (function(){
|
||||
{hit: MKDS_COLSOUNDS.HIT_ICE},
|
||||
],
|
||||
|
||||
0x10: //wall 3
|
||||
0x10: //wall oob
|
||||
[
|
||||
{hit: MKDS_COLSOUNDS.HIT_CONCRETE},
|
||||
{},
|
||||
|
||||
@@ -45,6 +45,8 @@ window.controlRaceCPU = function(nkm) {
|
||||
var destConst;
|
||||
var destPoint;
|
||||
|
||||
var item = false;
|
||||
|
||||
function fetchInput() {
|
||||
//basically as a cpu, we're really dumb and need a constant supply of points to drive to.
|
||||
//battle mode AI is a lot more complex, but since we're only going in one direction it can be kept simple.
|
||||
@@ -83,6 +85,7 @@ window.controlRaceCPU = function(nkm) {
|
||||
offTrans += 1/240;
|
||||
|
||||
if (offTrans >= 1) chooseNewOff();
|
||||
item = !item;
|
||||
|
||||
return {
|
||||
accel: accel, //x
|
||||
|
||||
@@ -5,6 +5,137 @@
|
||||
// by RHY3756547
|
||||
//
|
||||
|
||||
window.GraphicTester = function(rom) {
|
||||
|
||||
findGraphicsRecursive(rom);
|
||||
function listRecursive(resource, path) {
|
||||
path = path || "";
|
||||
var files = resource.list();
|
||||
for (var i=0; i<files.length; i++) {
|
||||
var file = files[i];
|
||||
console.log(path + file);
|
||||
if (file.toLowerCase().endsWith(".carc")) {
|
||||
listRecursive(new narc(lz77.decompress(resource.getFile(file))), path + file);
|
||||
}
|
||||
if (file.toLowerCase().endsWith(".nftr")) {
|
||||
testFont(new nftr(resource.getFile(file)), 0, path + file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findGraphicsRecursive(resource, path) {
|
||||
path = path || "";
|
||||
var files = resource.list();
|
||||
var pals = files.filter(x => x.toLowerCase().endsWith(".nclr"));
|
||||
var graphics = files.filter(x => x.toLowerCase().endsWith(".ncgr"));
|
||||
for (var i=0; i<files.length; i++) {
|
||||
var file = files[i];
|
||||
console.log(path + file);
|
||||
if (file.toLowerCase().endsWith(".carc")) {
|
||||
if (/\_..\./.exec(file) != null) continue; //a localization carc (format _us.carc). only scan the main ones. (+us)
|
||||
var mainCarc = new narc(lz77.decompress(resource.getFile(file)));
|
||||
var locCarc = resource.getFile(file.replace(".carc", "_us.carc"));
|
||||
if (locCarc != null) {
|
||||
//create a combo
|
||||
mainCarc = new narcGroup([mainCarc, new narc(lz77.decompress(locCarc))]);
|
||||
}
|
||||
findGraphicsRecursive(mainCarc, path + file);
|
||||
}
|
||||
if (file.toLowerCase().endsWith(".nscr")) {
|
||||
//screen
|
||||
//try to find a pal
|
||||
//...not a friend, like a color palette
|
||||
var palFile = mostSimilarString(file, pals, "b");
|
||||
var grFile = mostSimilarString(file, graphics.filter(x => !x.endsWith(".nce.ncgr")), "b");
|
||||
if (palFile != null && grFile != null) {
|
||||
var scr = new nscr(resource.getFile(file));
|
||||
var pal = new nclr(resource.getFile(palFile));
|
||||
var graphic = new ncgr(resource.getFile(grFile));
|
||||
|
||||
var flattener = new TileFlattener(pal, graphic, scr);
|
||||
|
||||
var render = flattener.toCanvas(true, 0, 0);
|
||||
|
||||
var split = document.createElement("h3");
|
||||
split.innerText = path + file;
|
||||
document.body.appendChild(split);
|
||||
split = document.createElement("h4");
|
||||
split.innerText = path + palFile + " " + path + grFile;
|
||||
document.body.appendChild(split);
|
||||
|
||||
document.body.appendChild(render);
|
||||
}
|
||||
}
|
||||
|
||||
if (file.toLowerCase().endsWith(".ncer")) {
|
||||
//cell resource
|
||||
//try to find a pal
|
||||
//...not a friend, like a color palette
|
||||
var palFile = mostSimilarString(file, pals, "o");
|
||||
var grFile = mostSimilarString(file, graphics, "o");
|
||||
if (palFile != null && grFile != null) {
|
||||
var cer = new ncer(resource.getFile(file));
|
||||
var pal = new nclr(resource.getFile(palFile));
|
||||
var graphic = new ncgr(resource.getFile(grFile));
|
||||
|
||||
var flattener = new TileFlattener(pal, graphic, cer);
|
||||
|
||||
var split = document.createElement("h3");
|
||||
split.innerText = path + file;
|
||||
document.body.appendChild(split);
|
||||
split = document.createElement("h4");
|
||||
split.innerText = path + palFile + " " + path + grFile;
|
||||
document.body.appendChild(split);
|
||||
|
||||
//render all images
|
||||
var imageCount = cer.cebk.imageCount;
|
||||
for (var j=0; j<imageCount; j++) {
|
||||
var render = flattener.toCanvas(true, j, 0);
|
||||
document.body.appendChild(render);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mostSimilarString(text, list, pref) {
|
||||
var bestString = null;
|
||||
var bestScore = 0;
|
||||
for (var i=0; i<list.length; i++) {
|
||||
var score = startSimilarity(text, list[i], pref);
|
||||
if (score > bestScore) {
|
||||
bestScore = score;
|
||||
bestString = list[i];
|
||||
}
|
||||
}
|
||||
return bestString;
|
||||
}
|
||||
|
||||
function countStr(text, char) {
|
||||
var count = 0;
|
||||
for (var i=0; i<text.length; i++) {
|
||||
if (text[i] == char) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function startSimilarity(text1, text2, pref) {
|
||||
var min = Math.min(text1.length, text2.length);
|
||||
var score = 0;
|
||||
for (var i=0; i<min; i++) {
|
||||
if (text1[i] != text2[i]) {
|
||||
if (pref != null) {
|
||||
score += countStr(text2.substr(i), pref) / 10;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
score++;
|
||||
}
|
||||
return score; //as similar as possible
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.IngameRes = function(rom) {
|
||||
var r = this;
|
||||
this.kartPhys = new kartphysicalparam(rom.getFile("/data/KartModelMenu/kartphysicalparam.bin"));
|
||||
@@ -21,6 +152,56 @@ window.IngameRes = function(rom) {
|
||||
this.RaceEffect = new spa(r.MainEffect.getFile("RaceEffect.spa"));
|
||||
|
||||
this.MainFont = new nftr(r.Main2D.getFile("marioFont.NFTR"));
|
||||
this.MFont = new nftr(r.Main2D.getFile("LC_Font_m.NFTR"));
|
||||
this.SFont = new nftr(r.Main2D.getFile("LC_Font_s.NFTR"));
|
||||
|
||||
//testFont(this.MainFont, 0);
|
||||
//testFont(this.MFont, 16*4);
|
||||
//testFont(this.SFont, 32*4);
|
||||
|
||||
/*
|
||||
var test = new GraphicTester(rom);
|
||||
listRecursive(rom);
|
||||
*/
|
||||
|
||||
|
||||
function testFont(font, off, name) {
|
||||
var all = Object.keys(font.charMap).join("");
|
||||
var split = document.createElement("h3");
|
||||
split.innerText = name;
|
||||
document.body.appendChild(split);
|
||||
|
||||
for (var i=0; i<4; i++) {
|
||||
var sliceF = Math.floor((all.length * i) / 4);
|
||||
var sliceT = Math.floor((all.length * (i+1)) / 4);
|
||||
|
||||
var canvas = font.drawToCanvas(all.substring(sliceF, sliceT), [[0, 0, 0, 0], [255, 0, 0, 255], [255, 255, 255, 255],
|
||||
[32, 0, 0, 255], [64, 0, 0, 255], [96, 0, 0, 255], [128, 0, 0, 255]]);
|
||||
document.body.appendChild(canvas);
|
||||
//canvas.style.position = "absolute";
|
||||
//canvas.style.left = 0;
|
||||
//canvas.style.top = off + "px";
|
||||
|
||||
//off += 16;
|
||||
}
|
||||
}
|
||||
|
||||
function listRecursive(resource, path) {
|
||||
path = path || "";
|
||||
var files = resource.list();
|
||||
for (var i=0; i<files.length; i++) {
|
||||
var file = files[i];
|
||||
console.log(path + file);
|
||||
if (file.toLowerCase().endsWith(".carc")) {
|
||||
listRecursive(new narc(lz77.decompress(resource.getFile(file))), path + file);
|
||||
}
|
||||
if (file.toLowerCase().endsWith(".nftr")) {
|
||||
if (file == "/selectFont.NFTR") debugger;
|
||||
testFont(new nftr(resource.getFile(file)), 0, path + file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//debugger;
|
||||
|
||||
this.getChar = getChar;
|
||||
|
||||
@@ -19,6 +19,8 @@ window.ItemController = function(scene) {
|
||||
t.changeItem = changeItem;
|
||||
t.update = update;
|
||||
t.draw = draw;
|
||||
t.createItem = createItem;
|
||||
t.removeItem = removeItem;
|
||||
|
||||
var RedShell, Banana, Bomb, BlueShell, Star, MultiItem, Shroom, TripleShroom, QueenShroom, Bullet, Ghost, Squid //these are all null
|
||||
|
||||
@@ -47,10 +49,25 @@ window.ItemController = function(scene) {
|
||||
}
|
||||
|
||||
function draw(mvMatrix, pMatrix, gl) {
|
||||
nitroRender.setShadBias(0.001);
|
||||
for (var i=0; i<t.items.length; i++) {
|
||||
var e = t.items[i];
|
||||
t.items[i].draw(mvMatrix, pMatrix, gl);
|
||||
}
|
||||
nitroRender.resetShadOff();
|
||||
}
|
||||
|
||||
function createItem(type, kart) {
|
||||
var item = new Item(scene, kart, type, t.curInd++);
|
||||
t.items.push(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
function removeItem(item) {
|
||||
var ind = t.items.indexOf(item);
|
||||
if (ind !== -1) {
|
||||
t.items.splice(ind, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function addItem(type, ownerKart, params) {
|
||||
|
||||
@@ -14,12 +14,28 @@ window.lsc = new (function() {
|
||||
this.sweepEllipse = sweepEllipse;
|
||||
this.pointInTriangle = pointInTriangle; //expose this because its kinda useful
|
||||
|
||||
function raycast(pos, dir, kclO, error, ignoreList) { //used for shells, bananas and spammable items. Much faster than sphere sweep. Error used to avoid falling through really small seams between tris.
|
||||
var t, colPlane, colPoint, emb, edge, colO, planeNormal;
|
||||
|
||||
function raycast(pos, dir, scn, error, ignoreList) { //used for shells, bananas and spammable items. Much faster than sphere sweep. Error used to avoid falling through really small seams between tris.
|
||||
var error = (error==null)?0:error;
|
||||
var t=1;
|
||||
var tris = getTriList(pos, dir, kclO);
|
||||
var colPlane = null;
|
||||
var colPoint = null; //can be calculated from t, but we calculate it anyway so why not include
|
||||
t=1;
|
||||
var tris = getTriList(pos, dir, scn.kcl);
|
||||
colPlane = null;
|
||||
colPoint = null; //can be calculated from t, but we calculate it anyway so why not include
|
||||
colO = null;
|
||||
|
||||
rayVTris(pos, dir, tris, null, ignoreList, null, error);
|
||||
|
||||
for (var i=0; i<scn.colEnt.length; i++) {
|
||||
var c = scn.colEnt[i];
|
||||
var col = c.getCollision();
|
||||
|
||||
if (vec3.distance(pos, c.pos) < c.colRad) {
|
||||
rayVTris(pos, dir, col.tris, col.mat, ignoreList, c, error, col.frame);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (var i=0; i<tris.length; i++) {
|
||||
//first, check if we intersect the plane within reasonable t.
|
||||
//only if this happens do we check if the point is in the triangle.
|
||||
@@ -29,7 +45,7 @@ window.lsc = new (function() {
|
||||
|
||||
if (ignoreList.indexOf(tri) != -1) continue;
|
||||
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertex1);
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertices[0]);
|
||||
var dist = vec3.dot(tri.Normal, pos) + planeConst;
|
||||
var modDir = vec3.dot(tri.Normal, dir);
|
||||
if (dist < 0 || modDir == 0) continue; //can't collide with back side of polygons! also can't intersect plane with ray perpendicular to plane
|
||||
@@ -44,24 +60,72 @@ window.lsc = new (function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (colPlane != null) {
|
||||
return {
|
||||
t: t,
|
||||
plane: colPlane,
|
||||
colPoint: colPoint,
|
||||
object: colO,
|
||||
normal: colPlane.Normal
|
||||
}
|
||||
} else return null;
|
||||
}
|
||||
|
||||
function rayVTris(pos, dir, tris, mat, ignoreList, targ, error, colFrame) {
|
||||
for (var i=0; i<tris.length; i++) {
|
||||
//first, check if we intersect the plane within reasonable t.
|
||||
//only if this happens do we check if the point is in the triangle.
|
||||
//we would also only do sphere sweep if this happens.
|
||||
var tri = tris[i];
|
||||
if (mat != null) {
|
||||
if (tri.colFrame === colFrame && tri.cache) {
|
||||
tri = tri.cache;
|
||||
} else {
|
||||
var oT = tri;
|
||||
tri = modTri(tris[i], mat);
|
||||
oT.cache = tri;
|
||||
oT.colFrame = colFrame;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreList.indexOf(tri) != -1) continue;
|
||||
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertices[0]);
|
||||
var dist = vec3.dot(tri.Normal, pos) + planeConst;
|
||||
var modDir = vec3.dot(tri.Normal, dir);
|
||||
if (dist < 0 || modDir == 0) continue; //can't collide with back side of polygons! also can't intersect plane with ray perpendicular to plane
|
||||
var newT = -dist/modDir;
|
||||
if (newT>0 && newT<t) {
|
||||
//we have a winner! check if the plane intersecion point is in the triangle.
|
||||
var pt = vec3.add([], pos, vec3.scale([], dir, newT))
|
||||
if (pointInTriangle(tri, pt, error)) {
|
||||
t = newT;
|
||||
colPlane = tri;
|
||||
colPoint = pt; //result!
|
||||
colO = targ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transformMat3Normal(out, a, m) {
|
||||
var x = a[0], y = a[1], z = a[2];
|
||||
out[0] = x * m[0] + y * m[4] + z * m[8];
|
||||
out[1] = x * m[1] + y * m[5] + z * m[9];
|
||||
out[2] = x * m[2] + y * m[6] + z * m[10];
|
||||
return out;
|
||||
}
|
||||
|
||||
function modTri(tri, mat) {
|
||||
var obj = {};
|
||||
obj.Vertex1 = vec3.transformMat4([], tri.Vertex1, mat);
|
||||
obj.Vertex2 = vec3.transformMat4([], tri.Vertex2, mat);
|
||||
obj.Vertex3 = vec3.transformMat4([], tri.Vertex3, mat);
|
||||
obj.Vertices = [];
|
||||
obj.Vertices[0] = vec3.transformMat4([], tri.Vertices[0], mat);
|
||||
obj.Vertices[1] = vec3.transformMat4([], tri.Vertices[1], mat);
|
||||
obj.Vertices[2] = vec3.transformMat4([], tri.Vertices[2], mat);
|
||||
|
||||
obj.Normal = vec3.transformMat3([], tri.Normal, mat3.fromMat4([], mat));
|
||||
obj.Normal = transformMat3Normal([], tri.Normal, mat);
|
||||
vec3.normalize(obj.Normal, obj.Normal);
|
||||
obj.CollisionType = tri.CollisionType;
|
||||
return obj;
|
||||
@@ -69,17 +133,16 @@ window.lsc = new (function() {
|
||||
|
||||
function scaleTri(tri, eDim) {
|
||||
var obj = {};
|
||||
obj.Vertex1 = vec3.divide([], tri.Vertex1, eDim);
|
||||
obj.Vertex2 = vec3.divide([], tri.Vertex2, eDim);
|
||||
obj.Vertex3 = vec3.divide([], tri.Vertex3, eDim);
|
||||
obj.Vertices = [];
|
||||
obj.Vertices[0] = vec3.divide([], tri.Vertices[0], eDim);
|
||||
obj.Vertices[1] = vec3.divide([], tri.Vertices[1], eDim);
|
||||
obj.Vertices[2] = vec3.divide([], tri.Vertices[2], eDim);
|
||||
|
||||
obj.Normal = tri.Normal
|
||||
obj.CollisionType = tri.CollisionType;
|
||||
return obj;
|
||||
}
|
||||
|
||||
var t, colPlane, colPoint, emb, edge, colO, planeNormal;
|
||||
|
||||
function sweepEllipse(pos, dir, scn, eDimensions, ignoreList) { //used for karts or things that need to occupy physical space.
|
||||
t=1;
|
||||
|
||||
@@ -140,7 +203,7 @@ window.lsc = new (function() {
|
||||
if (ignoreList.indexOf(oTri) != -1) continue;
|
||||
|
||||
var tri = (eDims)?scaleTri(tris[i], mat):modTri(tris[i], mat);
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertex1);
|
||||
var planeConst = -vec3.dot(tri.Normal, tri.Vertices[0]);
|
||||
var dist = vec3.dot(tri.Normal, pos) + planeConst;
|
||||
var modDir = vec3.dot(tri.Normal, dir);
|
||||
|
||||
@@ -200,14 +263,14 @@ window.lsc = new (function() {
|
||||
}
|
||||
|
||||
//no inside intersection check vertices:
|
||||
for (var j=1; j<=3; j++) {
|
||||
var vert = vec3.sub([], pos, tri["Vertex"+j]);
|
||||
for (var j=0; j<=2; j++) {
|
||||
var vert = vec3.sub([], pos, tri.Vertices[j]);
|
||||
var root = getSmallestRoot(vec3.dot(dir, dir), 2*vec3.dot(dir, vert), vec3.dot(vert, vert)-1, t);
|
||||
if (root != null) {
|
||||
t = root;
|
||||
colPlane = oTri;
|
||||
colO = targ;
|
||||
colPoint = vec3.clone(tri["Vertex"+j]); //result!
|
||||
colPoint = vec3.clone(tri.Vertices[j]); //result!
|
||||
planeNormal = tri.Normal;
|
||||
edge = false;
|
||||
}
|
||||
@@ -215,9 +278,9 @@ window.lsc = new (function() {
|
||||
|
||||
//... and lines
|
||||
|
||||
for (var j=1; j<=3; j++) {
|
||||
var vert = tri["Vertex"+j];
|
||||
var nextV = tri["Vertex"+((j%3)+1)];
|
||||
for (var j=0; j<=2; j++) {
|
||||
var vert = tri.Vertices[j];
|
||||
var nextV = tri.Vertices[(j+1)%3];
|
||||
|
||||
var distVert = vec3.sub([], vert, pos);
|
||||
var distLine = vec3.sub([], nextV, vert);
|
||||
@@ -277,9 +340,9 @@ window.lsc = new (function() {
|
||||
|
||||
function pointInTriangle(tri, point, error) { //barycentric check
|
||||
//compute direction vectors to the other verts and the point
|
||||
var v0 = vec3.sub([], tri.Vertex3, tri.Vertex1);
|
||||
var v1 = vec3.sub([], tri.Vertex2, tri.Vertex1);
|
||||
var v2 = vec3.sub([], point, tri.Vertex1);
|
||||
var v0 = vec3.sub([], tri.Vertices[2], tri.Vertices[0]);
|
||||
var v1 = vec3.sub([], tri.Vertices[1], tri.Vertices[0]);
|
||||
var v2 = vec3.sub([], point, tri.Vertices[0]);
|
||||
|
||||
//we need to find u and v across the two vectors v0 and v1 such that adding them will result in our point's position
|
||||
//where the unit length of both vectors v0 and v1 is 1, the sum of both u and v should not exceed 1 and neither should be negative
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
window.MKDSCONST = new (function() {
|
||||
|
||||
this.DAMAGE_SPIN = 0;
|
||||
this.DAMAGE_FLIP = 0;
|
||||
this.DAMAGE_EXPLODE = 0;
|
||||
this.DAMAGE_FLIP = 1;
|
||||
this.DAMAGE_EXPLODE = 2;
|
||||
|
||||
this.COURSEDIR = "/data/Course/";
|
||||
|
||||
|
||||
@@ -207,6 +207,8 @@ window.courseScene = function(mainNarc, texNarc, music, chars, options, gameRes)
|
||||
}
|
||||
entsToRemove = [];
|
||||
var mat = scn.camera.getView(scn, nitroRender.getViewWidth(), nitroRender.getViewHeight());
|
||||
|
||||
nitroAudio.updateListener(mat.pos, mat.mv);
|
||||
frame++;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ window.fileStore = new (function(){
|
||||
|| window.mozIndexedDB
|
||||
|| window.shimIndexedDB;
|
||||
|
||||
var request = indexedDB.open("MKJS_DB", 1);
|
||||
var request = indexedDB.open("MKJS-DB", 1);
|
||||
request.onerror = window.onerror;
|
||||
|
||||
request.onsuccess = function(event) {
|
||||
@@ -40,6 +40,18 @@ window.fileStore = new (function(){
|
||||
};
|
||||
}
|
||||
|
||||
function validateFiles() {
|
||||
var transaction = db.transaction(["files"]);
|
||||
var objectStore = transaction.objectStore("files");
|
||||
var request = objectStore.get("mkds.nds");
|
||||
request.onerror = function(event) {
|
||||
alert("Fatal database error!");
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
if (request.result == null) alert("Locally storing files failed!");
|
||||
};
|
||||
}
|
||||
|
||||
function downloadGame(url, callback) {
|
||||
if (typeof url == "string") {
|
||||
var xml = new XMLHttpRequest();
|
||||
@@ -77,6 +89,7 @@ window.fileStore = new (function(){
|
||||
callback(dat);
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
validateFiles();
|
||||
callback(dat);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user