basic vif decoder and displayer programmed using CBDL - at the moment, no rotation/yaw/pitch support, nor any support for z/depth. Also note that binary data cannot be properly loaded via iframe on an offline instance(e.g., no webserver), so test.vif has been copied to test.txt, allowing for browser-only/non-webserver running of JVIV
parent
fe52646c6d
commit
6b34f452aa
15
vif.html
15
vif.html
|
@ -0,0 +1,15 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="CBDL/CBDL.js"></script>
|
||||
<script type="text/javascript" src="vif.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
var jviv = new JVIV();
|
||||
jviv.Go();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
197
vif.js
197
vif.js
|
@ -0,0 +1,197 @@
|
|||
/* JVIV - JavaScript Voxel Image Viewer */
|
||||
JVIV = function() {
|
||||
this.requires = ["CBDL/CBDL_graphics.js"];
|
||||
var state = 0;
|
||||
var vif_loader;
|
||||
var loop;
|
||||
var display;
|
||||
var buffer = [];
|
||||
this.Main = function() {
|
||||
display = new CBDL.Graphics.Display(document.body, new CBDL.Graphics.VideoMode(512, 512, CBDL.Graphics.VM_SCALE), CBDL.Graphics.BACKEND.DIV);
|
||||
display.Init();
|
||||
display.Fill(25, 75, 25);
|
||||
vif_loader = new VL.Loader('test.txt');
|
||||
(loop = new CBDL.Loop(this, onLoop)).start();
|
||||
};
|
||||
|
||||
var offset = 0;
|
||||
var version = 0;
|
||||
var type = 0;
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var depth = 0;
|
||||
var palette_size = 0;
|
||||
var palettes = [];
|
||||
var voxels = [];
|
||||
var boxels = [];
|
||||
function onLoop(loop_time) {
|
||||
if (state == 0) {
|
||||
if (vif_loader.state == 1) {
|
||||
display.Fill(50, 50, 50);
|
||||
loadVoxel(vif_loader.raw_data);
|
||||
// We're done with the vif_loader, remove it
|
||||
vif_loader = null;
|
||||
// create our voxels as CBDL.Box(es)
|
||||
for (var i=0;i<voxels.length;i++) {
|
||||
boxels[i] = new display.Box({width: 1, height: 1}, {x: 1, y: 1}, {x:0, y:0});
|
||||
boxels[i].x = voxels[i][0];
|
||||
boxels[i].y = voxels[i][1];
|
||||
boxels[i].z = voxels[i][2];
|
||||
}
|
||||
state = 1;
|
||||
}
|
||||
} else if (state == 1) {
|
||||
drawVoxels();
|
||||
loop.stop();
|
||||
}
|
||||
return 100;
|
||||
};
|
||||
drawVoxels = function() {
|
||||
for(var i=0;i < boxels.length;i++) {
|
||||
console.log(boxels[i]);
|
||||
display.draw(boxels[i], {x: 0, y: 0}, {x: boxels[i].x, y: boxels[i].y});
|
||||
}
|
||||
};
|
||||
loadVoxel = function(buffer) {
|
||||
console.log(buffer);
|
||||
name = String.fromCharCode(buffer[0], buffer[1], buffer[2]);
|
||||
offset = 3;
|
||||
if (name == "VIF") {
|
||||
console.log("Magic Number found: "+name);
|
||||
}
|
||||
version = buffer[offset++];
|
||||
console.log("version: "+version);
|
||||
type = buffer[offset++];
|
||||
console.log("type: "+type);
|
||||
var palette_size = 0;
|
||||
for ( var i = 3; i >= 0; i--) {
|
||||
palette_size = (palette_size * 256) + buffer[offset+i];
|
||||
}
|
||||
palette_size += 1; // TODO: palette size in test.vif should be changed to 00 00 00 01, NOT absolutely 0
|
||||
offset += 4; // move past pallete byte range
|
||||
console.log("pallete size: "+palette_size);
|
||||
palettes = [];
|
||||
for (var i=0;i<palette_size;i++) {
|
||||
palettes[i] = [];
|
||||
palettes[i][0] = buffer[offset++]; // red
|
||||
palettes[i][1] = buffer[offset++]; // green
|
||||
palettes[i][2] = buffer[offset++]; // blue
|
||||
palettes[i][3] = buffer[offset++]; // alpha
|
||||
console.log("palette entry("+i+"): "+palettes[i]);
|
||||
}
|
||||
width = buffer[offset++];
|
||||
height = buffer[offset++];
|
||||
depth = buffer[offset++];
|
||||
console.log(width+"x"+height+"x"+depth);
|
||||
var i = 0;
|
||||
while(offset < buffer.length) {
|
||||
voxels[i] = [];
|
||||
voxels[i][0] = buffer[offset++]; // x
|
||||
voxels[i][1] = buffer[offset++]; // y
|
||||
voxels[i][2] = buffer[offset++]; // z
|
||||
voxels[i][3] = 0;
|
||||
for ( var j = 3; j >= 0; j--) {
|
||||
voxels[i][3] = (voxels[i][3] * 256) + buffer[offset+j]; // pallete reference
|
||||
}
|
||||
offset += 4; // move past pallete byte range
|
||||
console.log("voxel("+i+"): "+voxels[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
};
|
||||
}; CBDL.extend(CBDL.App, JVIV);
|
||||
|
||||
/* VIF Library */
|
||||
var VL = VL || {};
|
||||
/** int loadVif(url, &byte_array)
|
||||
Attempts to load the first parameter using XMLHttpRequest() as binary data into byte_array.
|
||||
Returns 1 on failure, 0 on success
|
||||
**/
|
||||
VL.Loader = function(vif_file) {
|
||||
this.state = 0;
|
||||
this.raw_data = [];
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.content = 'text\/plain; charset=x-user-defined'
|
||||
iframe.style.display = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
CBDL.addEvent(iframe, 'load', (function(iframe, scope) {
|
||||
return function() {
|
||||
var doc = (iframe.contentDocument || iframe.contentWindow.document || window[iframe.id].document);
|
||||
var pre = doc.body.getElementsByTagName("pre");
|
||||
if (typeof pre[0] === 'undefined') {
|
||||
data = doc.body.innerHTML;
|
||||
} else {
|
||||
data = pre[0].innerHTML;
|
||||
}
|
||||
for(var i=0;i<data.length;i++) {
|
||||
scope.raw_data[i] = data.charCodeAt(i) & 0xff;
|
||||
}
|
||||
scope.state = 1;
|
||||
// remove self w/ "delay" to prevent resource cancelled msg in Safari
|
||||
setTimeout((function(iframe) {
|
||||
return function() {
|
||||
document.body.removeChild(iframe);
|
||||
}
|
||||
})(iframe), 0);
|
||||
}
|
||||
})(iframe, this));
|
||||
iframe.src = vif_file;
|
||||
};
|
||||
VL.loadVif = function(vif_file, byte_array) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.content = 'text\/plain; charset=x-user-defined'
|
||||
iframe.style.display = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
CBDL.addEvent(iframe, 'load', (function(iframe, byte_array) {
|
||||
return function() {
|
||||
var doc = (iframe.contentDocument || iframe.contentWindow.document || window[iframe.id].document);
|
||||
var pre = doc.body.getElementsByTagName("pre");
|
||||
if (typeof pre[0] === 'undefined') {
|
||||
data = doc.body.innerHTML;
|
||||
} else {
|
||||
data = pre[0].innerHTML;
|
||||
}
|
||||
for(var i=0;i<data.length;i++) {
|
||||
byte_array[i] = data.charCodeAt(i) & 0xff;
|
||||
}
|
||||
// remove self w/ "delay" to prevent resource cancelled msg in Safari
|
||||
setTimeout((function(iframe) {
|
||||
return function() {
|
||||
document.body.removeChild(iframe);
|
||||
}
|
||||
})(iframe), 0);
|
||||
}
|
||||
})(iframe, byte_array));
|
||||
iframe.src = vif_file;
|
||||
/*CBDL.loadFile(vif_file, (function(byte_array) { return function(data) {
|
||||
for(var i=0;i<data.length;i++) {
|
||||
byte_array[i] = data.charCodeAt(i) & 0xff;
|
||||
}
|
||||
}})(byte_array));*/
|
||||
/*
|
||||
var file_request = new XMLHttpRequest();
|
||||
file_request.open('GET', vif_file, false);
|
||||
file_request.overrideMimeType('text\/plain; charset=x-user-defined');
|
||||
file_request.send();
|
||||
console.log(file_request.status);
|
||||
if (file_request.status != 200) return 1;
|
||||
console.log("LOL");
|
||||
for(var i=0;i<file_request.responseText.length;i++) {
|
||||
byte_array[i] = file_request.responseText.charCodeAt(i) & 0xff;
|
||||
}
|
||||
console.log('lol: '+byte_array);
|
||||
return byte_array; // unnecessary? @@ FIXME
|
||||
*/
|
||||
/* file_request.open("GET", "test.vif", true);
|
||||
file_request.responseType = "arraybuffer";
|
||||
file_request.onLoad = function(event) {
|
||||
var buffer = file_request.response;
|
||||
if (buffer) {
|
||||
var bytes = new Uint8Array(buffer);
|
||||
for (var i=0;i<bytes.byteLength;i++) {
|
||||
console.log(bytes[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
file_request.send(null);*/
|
||||
};
|
Loading…
Reference in New Issue