Files
2025-04-29 13:39:02 -05:00

486 lines
9.7 KiB
JavaScript

class Vec2 {
constructor(x,y){
if(typeof x === 'string'){
x=x.split(' ');
this.x=parseFloat(x[0]);
this.y=parseFloat(x[1]);
}else if(x instanceof Vec3){
this.x=x.x;
this.y=x.y;
}else if(x instanceof Vec2){
this.x=x.x;
this.y=x.y;
}else if(typeof x!=='undefined'){
this.x=x;
this.y=(typeof y==='number')?y:x;
}else{
this.x=this.y=0;
}
}
length(){
return Math.sqrt(this.x*this.x+this.y*this.y);
}
lengthSqr(){
return this.x*this.x+this.y*this.y;
}
normalize(){
return this.divide(this.length());
}
copy(){
return new Vec2(
this.x,
this.y
);
}
add(f) {
if(typeof f === 'number'){
return new Vec2(
this.x+f,
this.y+f
);
}else{
return new Vec2(
this.x+f.x,
this.y+f.y
);
}
}
subtract(f) {
if(typeof f === 'number'){
return new Vec2(
this.x-f,
this.y-f
);
}else{
return new Vec2(
this.x-f.x,
this.y-f.y
);
}
}
multiply(f){
if(typeof f === 'number'){
return new Vec2(
this.x*f,
this.y*f
);
}else{
return new Vec2(
this.x*f.x,
this.y*f.y
);
}
}
divide(f){
if(typeof f === 'number'){
return new Vec2(
this.x/f,
this.y/f
);
}else{
return new Vec2(
this.x/f.x,
this.y/f.y
);
}
}
dot(f){
return this.x*f.x+this.y*f.y;
}
reflect(f) {
return this.subtract(f.multiply(2*this.dot(f)));
}
perpendicular(){
return new Vec2(this.y, -this.x);
}
mix(v, a) {
return new Vec2(
this.x+(v.x-this.x)*a,
this.y+(v.y-this.y)*a
);
}
min(v) {
return new Vec2(
Math.min(this.x, v.x),
Math.min(this.y, v.y)
);
}
max(v) {
return new Vec2(
Math.max(this.x, v.x),
Math.max(this.y, v.y)
);
}
//smoothStep(min, max) {
// let x = Math.max(0, Math.min(1, (this.x-min.x)/(max.x-min.x)));
// let y = Math.max(0, Math.min(1, (this.y-min.y)/(max.y-min.y)));
// return new Vec2(x*x*(3-2*x), y*y*(3-2*y));
//}
toString(){
return this.x+' '+this.y;
}
toJSONString(){
return this.toString();
}
}
class Vec3 {
constructor(x,y,z){
if(typeof x === 'string'){
x=x.split(' ');
this.x=parseFloat(x[0]);
this.y=parseFloat(x[1]);
this.z=parseFloat(x[2]);
}else if(x instanceof Vec3){
this.x=x.x;
this.y=x.y;
this.z=x.z;
}else if(x instanceof Vec2){
this.x=x.x;
this.y=x.y;
this.z=0;
}else if(typeof x!=='undefined'){
this.x=x;
this.y=(typeof y==='number')?y:x;
this.z=(typeof z==='number')?z:((typeof y==='number')?0:x);
}else{
this.x=this.y=this.z=0;
}
}
length(){
return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);
}
lengthSqr(){
return this.x*this.x+this.y*this.y+this.z*this.z;
}
normalize(){
return this.divide(this.length());
}
copy(){
return new Vec3(
this.x,
this.y,
this.z
);
}
add(f) {
if(typeof f === 'number'){
return new Vec3(
this.x+f,
this.y+f,
this.z+f
);
}else if(f instanceof Vec2){
return new Vec3(
this.x+f.x,
this.y+f.y,
this.z
);
}else{
return new Vec3(
this.x+f.x,
this.y+f.y,
this.z+f.z
);
}
}
subtract(f) {
if(typeof f === 'number'){
return new Vec3(
this.x-f,
this.y-f,
this.z-f
);
}else if(f instanceof Vec2){
return new Vec3(
this.x-f.x,
this.y-f.y,
this.z
);
}else{
return new Vec3(
this.x-f.x,
this.y-f.y,
this.z-f.z
);
}
}
multiply(f){
if(typeof f === 'number'){
return new Vec3(
this.x*f,
this.y*f,
this.z*f
);
}else if(f instanceof Vec2){
return new Vec3(
this.x*f.x,
this.y*f.y,
this.z
);
}else{
return new Vec3(
this.x*f.x,
this.y*f.y,
this.z*f.z
);
}
}
divide(f){
if(typeof f === 'number'){
return new Vec3(
this.x/f,
this.y/f,
this.z/f
);
}else if(f instanceof Vec2){
return new Vec3(
this.x/f.x,
this.y/f.y,
this.z
);
}else{
return new Vec3(
this.x/f.x,
this.y/f.y,
this.z/f.z
);
}
}
cross(f){
return new Vec3(
this.y*f.z-this.z*f.y,
this.z*f.x-this.x*f.z,
this.x*f.y-this.y*f.x
);
}
dot(f){
return this.x*f.x+this.y*f.y+this.z*f.z;
}
reflect(f) {
return this.subtract(f.multiply(2*this.dot(f)));
}
mix(v, a) {
return new Vec3(
this.x+(v.x-this.x)*a,
this.y+(v.y-this.y)*a,
this.z+(v.z-this.z)*a
);
}
min(v) {
return new Vec3(
Math.min(this.x, v.x),
Math.min(this.y, v.y),
Math.min(this.z, v.z)
);
}
max(v) {
return new Vec3(
Math.max(this.x, v.x),
Math.max(this.y, v.y),
Math.max(this.z, v.z)
);
}
//smoothStep(min, max) {
// let x = Math.max(0, Math.min(1, (this.x-min.x)/(max.x-min.x)));
// let y = Math.max(0, Math.min(1, (this.y-min.y)/(max.y-min.y)));
// let z = Math.max(0, Math.min(1, (this.z-min.z)/(max.z-min.z)));
// return new Vec3(x*x*(3-2*x), y*y*(3-2*y), z*z*(3-2*z));
//}
toString(){
return this.x+' '+this.y+' '+this.z;
}
toJSONString(){
return this.toString();
}
}
class Vec4 {
constructor(x,y,z,w){
if(typeof x === 'string'){
x=x.split(' ');
this.x=parseFloat(x[0]);
this.y=parseFloat(x[1]);
this.z=parseFloat(x[2]);
this.w=parseFloat(x[3]);
}else if(x instanceof Vec4){
this.x=x.x;
this.y=x.y;
this.z=x.z;
this.w=x.w;
}else if(x instanceof Vec3){
this.x=x.x;
this.y=x.y;
this.z=x.z;
this.w=0;
}else if(x instanceof Vec2){
this.x=x.x;
this.y=x.y;
this.z=0;
this.w=0;
}else if(typeof x!=='undefined'){
this.x=x;
this.y=(typeof y==='number')?y:x;
this.z=(typeof z==='number')?z:((typeof y==='number')?0:x);
this.w=(typeof w==='number')?w:((typeof z==='number')?z:((typeof y==='number')?0:x));
}else{
this.x=this.y=this.z=this.w=0;
}
}
toString(){
return this.x+' '+this.y+' '+this.z+' '+this.w;
}
toJSONString(){
return this.toString();
}
}
class Mat4 {
constructor(){
this.m = [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1];
}
toString(){
return this.m[0]+' '+this.m[1]+' '+this.m[2]+' '+this.m[3]+' '+
this.m[4]+' '+this.m[5]+' '+this.m[6]+' '+this.m[7]+' '+
this.m[8]+' '+this.m[9]+' '+this.m[10]+' '+this.m[11]+' '+
this.m[12]+' '+this.m[13]+' '+this.m[14]+' '+this.m[15];
}
translation(v){
if(v instanceof Vec3){
this.m[12]=v.x;
this.m[13]=v.y;
this.m[14]=v.z;
return this;
}else if(v instanceof Vec2){
this.m[12]=v.x;
this.m[13]=v.y;
this.m[14]=0;
return this;
}else{
return new Vec3(this.m[12], this.m[13], this.m[14]);
}
}
right(){
return new Vec3(this.m[0], this.m[1], this.m[2]);
}
up(){
return new Vec3(this.m[4], this.m[5], this.m[6]);
}
forward(){
return new Vec3(this.m[8], this.m[9], this.m[10]);
}
toJSONString(){
return this.toString();
}
}
class Mat3 {
constructor(){
this.m = [1, 0, 0,
0, 1, 0,
0, 0, 1];
}
toString(){
return this.m[0]+' '+this.m[1]+' '+this.m[2]+' '
this.m[3]+' '+this.m[4]+' '+this.m[5]+' '
this.m[6]+' '+this.m[7]+' '+this.m[8];
}
translation(v){
if(v instanceof Vec2){
this.m[6]=v.x;
this.m[7]=v.y;
return this;
}else{
return new Vec2(this.m[6], this.m[7]);
}
}
angle(){
return Math.atan2(this.m[0], -this.m[1]) * (180.0 / Math.PI);
}
toJSONString(){
return this.toString();
}
}
class MediaPlaybackEvent {
static PLAYBACK_STOPPED = 0
static PLAYBACK_PLAYING = 1
static PLAYBACK_PAUSED = 2
}
function stringifyAdapter(key, value){
if (value && value.toJSONString){
return value.toJSONString();
}
return value;
}
this._Vec2 = Vec2.prototype;
this._Vec3 = Vec3.prototype;
this._Vec4 = Vec4.prototype;
this._Mat4 = Mat4.prototype;
this._Mat3 = Mat3.prototype;
this._Internal = {
updateScriptProperties(script, vars) {
vars = JSON.parse(vars);
Object.keys(vars).forEach((key) => {
if (script.scriptProperties.hasOwnProperty(key)) {
if (script.scriptProperties[key] instanceof Vec3){
script.scriptProperties[key] = new Vec3(vars[key]);
} else {
script.scriptProperties[key] = vars[key];
}
}
});
},
convertUserProperties(p) {
p = JSON.parse(p);
let r = {};
for (var k in p) {
switch (p[k].type){
default:
r[k] = p[k].value;
break;
case 'color':
r[k] = new Vec3(p[k].value);
break;
}
}
return r;
},
stringifyConfig(obj) {
return JSON.stringify(obj, stringifyAdapter);
}
};
this.createScriptProperties=function(){
var vars={};
var obj = {
order: 0,
addSlider: function(options){
vars[options.name] = options.value;
vars[options.name + '_config'] = { order: obj.order++, label: options.label,
min: options.min, max: options.max, mode: (options.integer===true)?'int':undefined };
return obj;
},
addCheckbox: function(options){
vars[options.name] = options.value;
vars[options.name + '_config'] = { order: obj.order++, label: options.label };
return obj;
},
addText: function(options){
vars[options.name] = options.value;
vars[options.name + '_config'] = { order: obj.order++, label: options.label };
return obj;
},
addCombo: function(options){
vars[options.name] = options.options[0].value;
vars[options.name + '_config'] = { order: obj.order++, label: options.label, options: options.options, mode: 'combo' };
return obj;
},
addColor: function(options){
vars[options.name] = options.value;
vars[options.name + '_config'] = { order: obj.order++, label: options.label };
return obj;
},
finish: function(){return vars;}
};
return obj;
}
this.shared = {};