Polygon Test & NAS6LIB Help document






 






//################################################################
//Programed by NAS6
//################################################################
//./javascripts/nas6lib/timer.js
//./javascripts/nas6lib/vector.js
//./javascripts/nas6lib/matrix.js
//./javascripts/nas6lib/quaternion.js
//./javascripts/nas6lib/keyboard.js
//################################################################
//timer,vector,matrix,quaternion,logarithm quaternion,2/3D CG matrix calculation javascript library
//################################################################





back





How to write NAS6LIB template with X3DOM

This explains how homogeneous coordinates are defined in the order w, x, y, z, ... The order is different, but the functionality is the same...
testpoly.htm

testpoly.zip

・./testpoly.htm


<!DOCTYPE html>
<html lang="ja">
<head>
<title>Polygon Test & NAS6LIB Help Document</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script language="JavaScript" type="text/javascript" src="./javascripts/x3dom/jquery-2.1.4.min.js" ></script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>
<script language="JavaScript" type='text/javascript' src='./javascripts/x3dom/x3dom.js'> </script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>


<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/timer.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/vector.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/matrix.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/quaternion.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6/help.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6/testpoly.js"></script>

<style>
article, aside, dialog, figure, footer, header,
hgroup, menu, nav, section { display: block; }
#x3dabs{
    position: absolute;
    float: left;
    top: 76px;
    left: 20px;
    background:#8080b0;
    border: 2px #000000 solid;
}
</style>
</head>
<body text="black" link="#3333cc" vlink="#663399" alink="#cc0000" bgcolor="#faebf1" background="./img/kumausagineko.jpg">
<b>
<h1>Polygon Test & NAS6LIB Help Document</h1>

<div style = 'width:500px; height:250px; border: 0px; overflow:hidden;'>

<x3d id='x3dabs' width='500px' height='250px'>
    <scene>
        <Viewpoint id='viewp001' position='0 3 20' orientation='0 1 0 0' description='camera'></Viewpoint>

	<directionalLight id="directional" direction='1 -1 1' on ="TRUE" intensity='1.0' shadowIntensity='0.0'></directionalLight> 
	
        <Transform center='0 0 0' translation='0 0 8' id='box0' DEF='box0'>
            <Transform rotation='0 1 0 0' id='box1' DEF='box1'>
            <shape>
                <appearance>
                    <ImageTexture  url="./img/koala.jpg"></ImageTexture>
                    <material diffuseColor='0.8 0.8 0.8'></material>
                </appearance>
                <Box size = '5 5 5'></Box>
            </shape>
            </Transform>
        </Transform>
    </scene>
</x3d>
</div>

// ……… Omitted …………
</b>
</font>
</body>
</html>



・./javascripts/nas6/testpoly.js


var TMan = new N6LTimerMan();  //timer manager
jQuery(document).ready(function(){
  TMan.add();
  TMan.timer[0].setalerm(function() { GLoop(0); }, 50);  //set main loop
});

var bx = new N6LVector(new Array('1','0','0','8'), true);  //pos Box
var bm = new N6LMatrix(4).UnitMat();  //mat Box

//main loop
function GLoop(id){

// ……… Omitted …………
	
  var MatWK = new N6LMatrix(4).UnitMat();
  var v = new N6LVector(4, false);
  //unit vector//単位ベクトル
  var ax = new N6LVector(4, true).UnitVec(1);
  var ay = new N6LVector(4, true).UnitVec(2);
  var az = new N6LVector(4, true).UnitVec(3);

  //rot mov obj
  MatWK = MatWK.RotAxis(ay, 1.0 * Math.PI / 180.0);  //around y axis rotate 1 degree
  bx = MatWK.Mul(bx);  //pos Box multiply matrix

  //unit vector
  ax = ax.UnitVec(1);
  ay = ay.UnitVec(2);
  az = az.UnitVec(3);
  //rot obj
  MatWK = new N6LMatrix(bm);  //mat Box
  MatWK = MatWK.RotAxis(az, 3.0 * Math.PI / 180.0);  //around z axis rotate 3 degree
  MatWK = MatWK.RotAxis(ay, 2.0 * Math.PI / 180.0);  //around y axis rotate 2 degree
  bm = MatWK.RotAxis(ax, 1.0 * Math.PI / 180.0);     //around x axis rotate 1 degree

  v = bm.Vector();  //rot vector

  var angle = bm.EulerAngle(3, 2, 1);  //rotate order ZYX

// ↑ First half: ↓ Second half
	
  //apply x3dom
  var pos = bx.ToX3DOM(true);
  var elm = document.getElementById('box0');
  elm.setAttribute('translation', pos.toString());
  var rot = v.ToX3DOM();
  elm = document.getElementById('box1');
  elm.setAttribute('rotation', rot.toString());

  //for debug
  elm = document.getElementById('debug');
  elm.innerText = 
  'EulerAngle(rotate per degree z(3)_y(2)_x(1))\n' + angle.x[0] + ' ' + Math.floor(angle.x[1] * 180.0 / Math.PI) + ' ' + Math.floor(angle.x[2] * 180.0 / Math.PI) + ' ' + Math.floor(angle.x[3] * 180.0 / Math.PI); 

  TMan.timer[id].setalerm(function() { GLoop(id); }, 50);  //reset main loop
}

// ... the rest is omitted ...



・How to write a header


<head>
<title>Please enter a title</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script language="JavaScript" type="text/javascript" src="./javascripts/x3dom/jquery-2.1.4.min.js" ></script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>
<script language="JavaScript" type='text/javascript' src='./javascripts/x3dom/x3dom.js'> </script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>


<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/timer.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/vector.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/matrix.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/quaternion.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6/testpoly.js"></script>

<style>
article, aside, dialog, figure, footer, header,
hgroup, menu, nav, section { display: block; }
#x3dabs{
    position: absolute;
    float: left;
    top: 76px;
    left: 20px;
    background:#8080b0;
    border: 2px #000000 solid;
}
</style>
</head>



This is almost copy and paste


<head>
<title>Please enter a title</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script language="JavaScript" type="text/javascript" src="./javascripts/x3dom/jquery-2.1.4.min.js" ></script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>
<script language="JavaScript" type='text/javascript' src='./javascripts/x3dom/x3dom.js'> </script>
<link rel='stylesheet' type='text/css' href='./javascripts/x3dom/x3dom.css'>


It's almost a formula.


<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/timer.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/vector.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/matrix.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6lib/quaternion.js"></script>
<script language="JavaScript" type="text/javascript" src="./javascripts/nas6/testpoly.js"></script>


Here you can register the necessary components such as the NAS6 library.


<style>
article, aside, dialog, figure, footer, header,
hgroup, menu, nav, section { display: block; }
#x3dabs{
    position: absolute;
    float: left;
    top: 76px;
    left: 20px;
    background:#8080b0;
    border: 2px #000000 solid;
}
</style>
</head>


X3DOM window style sheet


・How to write objects


<div style = 'width:500px; height:250px; border: 0px; overflow:hidden;'>

<x3d id='x3dabs' width='500px' height='250px'>
    <scene>
        <Viewpoint id='viewp001' position='0 3 20' orientation='0 1 0 0' description='camera'></Viewpoint>

	<directionalLight id="directional" direction='1 -1 1' on ="TRUE" intensity='1.0' shadowIntensity='0.0'></directionalLight> 
	
        <Transform center='0 0 0' translation='0 0 8' id='box0' DEF='box0'>
            <Transform rotation='0 1 0 0' id='box1' DEF='box1'>
            <shape>
                <appearance>
                    <ImageTexture  url="./img/koala.jpg"></ImageTexture>
                    <material diffuseColor='0.8 0.8 0.8'></material>
                </appearance>
                <Box size = '5 5 5'></Box>
            </shape>
            </Transform>
        </Transform>
    </scene>
</x3d>
</div>



The reason why <x3d> is enclosed in <div> is to match the layout.

Since orientation and rotation are rotation vectors, use N6LMatrix to perform matrix calculations.
Convert this to a rotation vector using N6LMatrix.Vector(); and then insert it.

There are various objects such as Box and Sphere.
For more information, see the original x3dom website.

The reason why <shape> is enclosed twice in <transform> is
to translate the outer <transform> and rotate it in place using the inner <transform>.
The part enclosed in <transform> is the description part of the object.
If you want to change the size of the box, change Box.size.
If you want to change the texture, change ImageTexture.url.



・Register the main loop


var TMan = new N6LTimerMan();  //timer manager
jQuery(document).ready(function(){
  TMan.add();
  TMan.timer[0].setalerm(function() { GLoop(0); }, 50);  //set main loop
});



In the global scope
var TMan = new N6LTimerMan(); // Timer manager
Construct the timer manager

When the page is reloaded, tweak
jQuery(document).ready(function(){});
To register the main loop when the page is reloaded, use


To construct the id 0 timer TMan.timer[0] in the timer manager, use TMan.add();

TMan.timer[0].setalerm(function() { GLoop(0); }, 50); // Set the main loop

Register the main loop with setalerm(); in function() { GLoop(0); }
50 means that the main loop will be called after 50 milliseconds


・Implement the main loop


var bx = new N6LVector(new Array('1','0','0','8'), true);  //pos Box
var bm = new N6LMatrix(4).UnitMat();  //mat Box

//main loop
function GLoop(id){

// ……… Omitted …………

  var MatWK = new N6LMatrix(4).UnitMat();
  var v = new N6LVector(4, false);
  //unit vector
  var ax = new N6LVector(4, true).UnitVec(1);
  var ay = new N6LVector(4, true).UnitVec(2);
  var az = new N6LVector(4, true).UnitVec(3);

  //rot mov obj
  MatWK = MatWK.RotAxis(ay, 1.0 * Math.PI / 180.0);  //around y axis rotate 1 degree
  bx = MatWK.Mul(bx);  //pos Box multiply matrix

  //unit vector
  ax = ax.UnitVec(1);
  ay = ay.UnitVec(2);
  az = az.UnitVec(3);
  //rot obj
  MatWK = new N6LMatrix(bm);  //mat Box
  MatWK = MatWK.RotAxis(az, 3.0 * Math.PI / 180.0);  //around z axis rotate 3 degree
  MatWK = MatWK.RotAxis(ay, 2.0 * Math.PI / 180.0);  //around y axis rotate 2 degree
  bm = MatWK.RotAxis(ax, 1.0 * Math.PI / 180.0);     //around x axis rotate 1 degree

  v = bm.Vector();  //rot vector

  var angle = bm.EulerAngle(3, 2, 1);  //rotate order ZYX

// ↑ First half: ↓ Second half

  //apply x3dom
  var pos = bx.ToX3DOM(true);
  var elm = document.getElementById('box0');
  elm.setAttribute('translation', pos.toString());
  var rot = v.ToX3DOM();
  elm = document.getElementById('box1');
  elm.setAttribute('rotation', rot.toString());

  //for debug
  elm = document.getElementById('debug');
  elm.innerText = 
  'EulerAngle(rotate per degree z(3)_y(2)_x(1))\n' + angle.x[0] + ' ' + Math.floor(angle.x[1] * 180.0 / Math.PI) + ' ' + Math.floor(angle.x[2] * 180.0 / Math.PI) + ' ' + Math.floor(angle.x[3] * 180.0 / Math.PI); 

  TMan.timer[id].setalerm(function() { GLoop(id); }, 50);  //reset main loop
}



In the first half, use NAS6LIB to calculate the rotation matrix.
Since orientation and rotation are rotation vectors, use N6LMatrix to calculate the matrix.
Convert to a rotation vector using N6LMatrix.Vector() and then enter the result.

In the second half, apply the value to x3dom.
Note that in homogeneous coordinates, NAS6LIB uses the order w, x, y, z..., while x3dom uses the order x, y, z, w....
Convert to SFVecXf using N6LVector.ToX3DOM(b). Setting b=true changes the degree of Vector from 4 to 3.
Convert from sf=SFVecXf using N6LVector.FromX3DOM(sf).
Convert to SFMatrix4f using N6LMatrix.ToX3DOM().
Convert from sf=SFMatrix4f using N6LMatrix.FromX3DOM(sf).

Get the element with document.getElementById();
Apply the value to x3dom with setAttribute('name to change', SFVecXf.toString());

Finally, reset the main loop with TMan.timer[id].setalerm(function() { GLoop(id); }, 50); //reset main loop//Reset main loop
and you're done.

This is basically how it's written
The rest is free to write tags and javascript
and you can do pretty much anything.


Potential bugs (places to overlook):
・Division by zero, negative root, undefined
・Value or absolute value over 1.0 (not normalized, outside the range of inverse trigonometric functions, etc.)
・objA = new N6LType(objB); Forgot to do a deep copy by writing objA = objB; instead of new N6LType(objB);
・bHomo flag related (bHomo is a homogeneous coordinate matrix N6LMatrix, and N6LVector for each row is false
When trying to extract it as an axis, .SetHomo(true) must be used
After that, when using the original matrix, .SetHomo(false) must be used, etc.)
*Because SetHomo() was the source of bugs, it no longer changes this when it is executed, but instead returns the return value
*Safer Get/Set-Col/Row() functions have been provided for row and column manipulation




How to write NAS6LIB template with ThreeJS




This is an explanation of homogeneous coordinates defined in the order w, x, y, z, .... The order is different, but the functionality is the same...


How to use THREE.JS

THREE.JSTest.htm

THREE.JSTest.zip

60FPSTest.htm

60FPSTest.zip



・./test3js.htm


<!DOCTYPE html>
<html lang="ja">
<head>
<title>THREEJSTEST</title>
  <meta charset="UTF-8" />
  <script src="./javascripts/nas6lib/timer.js"></script>
  <script src="./javascripts/threejs/three.js"></script>

<script>

window.addEventListener("DOMContentLoaded", init);
var TMan = new N6LTimerMan();  //TimerManager

function init() {
  const width = 500;
  const height = 250;

  const renderer = new THREE.WebGLRenderer({
    canvas: document.querySelector("#cnv0")
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    45,
    width / height,
    1,
    10000
  );
  camera.position.set(0, 0, 20);

  // create box
  const geometry = new THREE.BoxGeometry(5, 5, 5);
  const loader = new THREE.TextureLoader();
  const texture = loader.load('./img/koala.jpg');
  const textureF = loader.load('./img/koalaF.jpg');
  // Add texture to material
  const materials = [
    new THREE.MeshStandardMaterial({map: textureF}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture})
  ];
  // create mesh
  const box = new THREE.Mesh(geometry, materials);
  box.position.set(0, 0, 8);
  scene.add(box);

  // DirectionalLight
  const light = new THREE.DirectionalLight(0xffffff);
  light.intensity = 2; // light.intensity twice
  light.position.set(1, 1, 1);
  // add scene
  scene.add(light);

  TMan.add();
  TMan.timer[0].setalerm(function() { Loop(0); }, 50);  //set main loop


  // main loop
  function Loop(id) {

    box.rotation.x += 1.0 * Math.PI / 180.0;//Rotate 1 degree around the x axis
    box.rotation.y += 2.0 * Math.PI / 180.0;//Rotate 2 degree around the y axis
    box.rotation.z += 3.0 * Math.PI / 180.0;//Rotate 3 degree around the z axis

    // rendering
    renderer.render(scene, camera);

    TMan.timer[id].setalerm(function() { Loop(id); }, 50);  //set main loop
  }

<!--
/*
  // First run
  Loop();

  // main loop
  function Loop() {
    requestAnimationFrame(Loop);

    box.rotation.x += 1.0 * Math.PI / 180.0;//Rotate 1 degree around the x axis
    box.rotation.y += 2.0 * Math.PI / 180.0;//Rotate 2 degree around the y axis
    box.rotation.z += 3.0 * Math.PI / 180.0;//Rotate 3 degree around the z axis

    renderer.render(scene, camera);
  }
*/
//-->

}

</script>

<style>
article, aside, dialog, figure, footer, header,
hgroup, menu, nav, section { display: block; }
#cnv0{
    position: absolute;
    float: left;
    top: 640px;
    left: 20px;
    background:#8080b0;
    border: 2px #000000 solid;
}
</style>

</head>

<body text="black" link="#3333cc" vlink="#663399" alink="#cc0000" bgcolor="#faebf1" background="./img/kumausagineko.jpg">
<font size="3">
<br>
<br>
<b>
<h1>THREEJSTEST</h1>
<br>
<div style = 'width:500px; height:250px; border: 0px; overflow:hidden;'>
  <canvas id="cnv0" name="cnv0" width="500" height="250"></canvas>
</div>
<br>
<br>
<br>
</b>
</font>
<br>
<br>
<hr>
<br>
<br>
<a href="./index.htm">back</a><br>
<br>
<br>
</body>
</html>






・How to write the header



<!DOCTYPE html>
<html lang="ja">
<head>
<title>Please enter a title</title>
  <meta charset="UTF-8" />

// ………… Omitted ………
</head>



You can pretty much just copy and paste this


・Registering components


  <script src="./javascripts/nas6lib/timer.js"></script>
  <script src="./javascripts/threejs/three.js"></script>



Please register library components such as three.js.


・Stylesheet


<style>
article, aside, dialog, figure, footer, header,
hgroup, menu, nav, section { display: block; }
#cnv0{
    position: absolute;
    float: left;
    top: 640px;
    left: 20px;
    background:#8080b0;
    border: 2px #000000 solid;
}
</style>



Please adjust the style sheet as necessary.


・Target Canvas


<div style = 'width:500px; height:250px; border: 0px; overflow:hidden;'>
  <canvas id="cnv0" name="cnv0" width="500" height="250"></canvas>
</div>



The reason why the <canvas> is enclosed in a <div> is to adjust the layout.
Please write it within the <body> tag.


・Script section



<script>

window.addEventListener("DOMContentLoaded", init);
var TMan = new N6LTimerMan();  //Timer manager

function init() {
  const width = 500;
  const height = 250;

  const renderer = new THREE.WebGLRenderer({
    canvas: document.querySelector("#cnv0")
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    45,
    width / height,
    1,
    10000
  );
  camera.position.set(0, 0, 20);

  // create box
  const geometry = new THREE.BoxGeometry(5, 5, 5);
  const loader = new THREE.TextureLoader();
  const texture = loader.load('./img/koala.jpg');
  const textureF = loader.load('./img/koalaF.jpg');
  // Add texture to material
  const materials = [
    new THREE.MeshStandardMaterial({map: textureF}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture})
  ];
  // create mesh
  const box = new THREE.Mesh(geometry, materials);
  box.position.set(0, 0, 8);
  scene.add(box);

  // DirectionalLight
  const light = new THREE.DirectionalLight(0xffffff);
  light.intensity = 2; // Double the light intensity
  light.position.set(1, 1, 1);
  // add scene
  scene.add(light);

  TMan.add();
  TMan.timer[0].setalerm(function() { Loop(0); }, 50);  //set main loop


  //main loop 
  function Loop(id) {

    box.rotation.x += 1.0 * Math.PI / 180.0;//Rotate 1 degree around the x axis
    box.rotation.y += 2.0 * Math.PI / 180.0;//Rotate 2 degree around the y axis
    box.rotation.z += 3.0 * Math.PI / 180.0;//Rotate 3 degree around the z axis

    // rendering
    renderer.render(scene, camera);

    TMan.timer[id].setalerm(function() { Loop(id); }, 50);  //set main loop
  }

<!--
/*
  // first run
  Loop();

  function Loop() {
    requestAnimationFrame(Loop);

    box.rotation.x += 1.0 * Math.PI / 180.0;//Rotate 1 degree around the x axis
    box.rotation.y += 2.0 * Math.PI / 180.0;//Rotate 2 degree around the y axis
    box.rotation.z += 3.0 * Math.PI / 180.0;//Rotate 3 degree around the z axis

    renderer.render(scene, camera);
  }
*/
//-->

}

</script>




N6LVector.To3JS(b)
N6LVector.From3JS(ary)
N6LMatrix.To3JS()
N6LMatrix.From3JS(ary)

argument:ary:Array():case:b:4→3 true

Added N6L←→THREE converter


Basically, I think you can make almost anything with this writing style








Javascript multi-threaded testing using N6LTimerMan.htm

Javascript multi-threaded testing using N6LTimerMan.zip




Using N6LTimerMan, you can easily implement multi-threading in JavaScript.

・./mttest.htm (script part)


window.addEventListener("DOMContentLoaded", init);
var TMan = new N6LTimerMan();  //timer manager
var pos = [ new N6LVector(4, true), new N6LVector(4, true), new N6LVector(4, true), new N6LVector(4, true)];
var th = [0, 0, 0, 0];
var dt = [50, 100, 150, 500];
var spd = 5.0;
var cnt = 0;
var div = 72;
var sph3;

function init() {
  const width = 500;
  const height = 250;

  const renderer = new THREE.WebGLRenderer({
    canvas: document.querySelector("#cnv0")
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    45,
    width / height,
    1,
    10000
  );
  camera.position.set(0, 0, 20);

  // create sphere
  const sph0geometry = new THREE.SphereGeometry(1, 128, 128);
  // Set the color of the material
  const sph0material = new THREE.MeshBasicMaterial({ color: '#ff0000'});
  // create mesh
  const sph0 = new THREE.Mesh(sph0geometry, sph0material);
  sph0.position.set(0, 6, 0);
  pos[0] = new N6LVector([1, 0, 6, 0], true);
  // create sphere
  const sph1geometry = new THREE.SphereGeometry(1, 128, 128);
  // Set the color of the material
  const sph1material = new THREE.MeshBasicMaterial({ color: '#00ff00'});
  // create mesh
  const sph1 = new THREE.Mesh(sph1geometry, sph1material);
  sph1.position.set(0, 2, 0);
  pos[1] = new N6LVector([1, 0, 2, 0], true);
  // create sphere
  const sph2geometry = new THREE.SphereGeometry(1, 128, 128);
  // Set the color of the material
  const sph2material = new THREE.MeshBasicMaterial({ color: '#0000ff'});
  // create mesh
  const sph2 = new THREE.Mesh(sph2geometry, sph2material);
  sph2.position.set(0, -2, 0);
  pos[2] = new N6LVector([1, 0, -2, 0], true);
  // create spher
  const sph3geometry = new THREE.SphereGeometry(1, 128, 128);
  // Set the color of the material
  const sph3material = new THREE.MeshBasicMaterial({ color: '#808080'});
  // create mesh
  sph3 = new THREE.Mesh(sph3geometry, sph3material);
  sph3.position.set(0, -6, 0);
  pos[3] = new N6LVector([1, 0, -6, 0], true);
  scene.add(sph0);
  scene.add(sph1);
  scene.add(sph2);
  scene.add(sph3);

  // DirectionalLight
  const light = new THREE.DirectionalLight(0xffffff);
  light.position.set(1, 1, 1);
  // add scene
  scene.add(light);

  //add timer
  TMan.add();
  TMan.add();
  TMan.add();
  TMan.add();
  TMan.add();
  
  //first run
  Loop0(0);
  Loop1(1);
  Loop2(2);
  Loop3(3);
  RDLoop(4);


  //Implementing multiple main loops
  function RDLoop(id) {
    
    // rendering
    renderer.render(scene, camera);
    TMan.timer[id].setalerm(function() { RDLoop(id); }, 50);
  }
 
  function Loop0(id) {

    th[id] += spd * Math.PI / 180.0;
    sph0.position.set(5 * Math.sin(th[id]) + pos[id].x[1], 6, 0);

    TMan.timer[id].setalerm(function() { Loop0(id); }, dt[id]);
  }
 
  function Loop1(id) {

    th[id] += spd * Math.PI / 180.0;
    sph1.position.set(5 * Math.sin(th[id]) + pos[id].x[1], 2, 0);

    TMan.timer[id].setalerm(function() { Loop1(id); }, dt[id]);
  }
 
  function Loop2(id) {

    th[id] += spd * Math.PI / 180.0;
    sph2.position.set(5 * Math.sin(th[id]) + pos[id].x[1], -2, 0);

    TMan.timer[id].setalerm(function() { Loop2(id); }, dt[id]);
  }

  function Loop3(id) {

    th[id] += spd * Math.PI / 180.0;

    var col1 = new N6LHsv(0, [255, 255, 0, 0]);
    var col2 = new N6LHsv(0, [255, 255, 0, 0]);
    var col = col1.HsvGrd(div, cnt, col2.ahsv, 1);
    var str = col.Str();
    cnt++;

    sph3.material.color.set(str);
    sph3.position.set(5 * Math.sin(th[id]) + pos[id].x[1], -6, 0);

    var c = (Math.cos(th[id]) + 1.0) / 2.0;
    dt[id] = 50  + c * 450; //Variable timer from 50 to 500 [ms]

    TMan.timer[id].setalerm(function() { Loop3(id); }, dt[id]);
  }

}




var TMan = new N6LTimerMan();  //timer manager
var pos = [ new N6LVector(4, true), new N6LVector(4, true), new N6LVector(4, true)];
var th = [0, 0, 0];
var dt = [50, 100, 150, 500];
var spd = 5.0;



The timer manager and the ball's position (pos), angle (th), speed (spd), and multithread interval (dt) are declared.


var cnt = 0;
var div = 72;
var sph3;



Used to change the color of the sphere.

Create a 3D scene in init().


//add timer
TMan.add();
TMan.add();
TMan.add();
TMan.add();
TMan.add();



Create five timers.


//first run
Loop0(0);
Loop1(1);
Loop2(2);
Loop3(3);
RDLoop(4);



Each will be executed for the first time.


function RDLoop(id) {
    
  // rendering
  renderer.render(scene, camera);
  TMan.timer[id].setalerm(function() { RDLoop(id); }, 50);
}



This is the rendering thread.

Loop0(), Loop1(), Loop2(), and Loop3() are the threads for each ball's movement.

Let's look at Loop0().


function Loop0(id) {

  th[id] += spd * Math.PI / 180.0;
  sph0.position.set(5 * Math.sin(th[id]) + pos[id].x[1], 6, 0);

  TMan.timer[id].setalerm(function() { Loop0(id); }, dt[id]);
}



th[id] += spd * Math.PI / 180.0;

Here, th[id] is added by the angle spd degrees.

sph0.position.set(5 * Math.sin(th[id]) + pos[id].x[1], 6, 0);

Here we apply the position calculated from the angle to the sphere

TMan.timer[id].setalerm(function() { Loop0(id); }, dt[id]);

Here, Loop0(id) is recursively called at intervals of dt[id].

var dt = [50, 100, 150, 500];
This was declared like this, so
Loop0 will be called every 50ms, Loop1 every 100ms, and Loop2 every 150ms.


  function Loop3(id) {

    th[id] += spd * Math.PI / 180.0;

    var col1 = new N6LHsv(0, [255, 255, 0, 0]);
    var col2 = new N6LHsv(0, [255, 255, 0, 0]);
    var col = col1.HsvGrd(div, cnt, col2.ahsv, 1);
    var str = col.Str();
    cnt++;

    sph3.material.color.set(str);
    sph3.position.set(5 * Math.sin(th[id]) + pos[id].x[1], -6, 0);

    var c = (Math.cos(th[id]) + 1.0) / 2.0;
    dt[id] = 50  + c * 450; //50~500[ms]の可変タイマー

    TMan.timer[id].setalerm(function() { Loop3(id); }, dt[id]);
  }



Loop3 creates an HSV gradient divided into div(72) around RGB from col1(ARGB:FFFF0000,AHSV:100,0,100,100) to col2(ARGB:FFFF0000,AHSV:100,0,100,100). Color is applied with sph3.material.color.set(str);. var c = (Math.cos(th[id]) + 1.0) / 2.0; dt[id] = 50 + c * 450; //50 to 500[ms] variable timer
The code is added, so it is a variable timer of 50 to 500[ms]

And so, multithreading can be achieved very easily using N6LTimerMan

Note that only one software timer is executed on the N6LTimerMan core
The timers managed by N6LTimerMan are distributed among the cores
so that resources are not strained as much as possible
Therefore, calling N6LTimer.add() many times does not have much effect. There is no problem.
Well, of course, timers with short intervals will put a load on the system.

The core operation of N6LTimerMan is to repeatedly run the core timer check thread
with one of the fastest software timers in N6LTimerMan.
measure the time, and when the time set by setalerm() for each timer has elapsed,
call the registered function for each timer.
That's all it does.

N6LTimerMan.changeinterval(INT); //Change timer check interval
You can set the core timer check interval with





Skybox settings and basic FPS controls



THREE.JSBasic.htm

THREE.JSBasic.zip



Basic FPS



window.addEventListener("DOMContentLoaded", init);
var TMan = new N6LTimerMan();  //timer manager
var boxies = [];
var renderer;
var camera;
var scene;

function init() {
  const width = 500;
  const height = 250;

  renderer = new THREE.WebGLRenderer({
    canvas: document.querySelector("#cnv0")
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
    45,
    width / height,
    1,
    10000
  );
  camera.position.set(0, 0, 20);

  // create box
  const geometry = new THREE.BoxGeometry(5, 5, 5);
  const loader = new THREE.TextureLoader();
  const texture = loader.load('./img/koala.jpg');
  const textureF = loader.load('./img/koalaF.jpg');
  // Set the texture on the material
  const materials = [
    new THREE.MeshStandardMaterial({map: textureF}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture}),
    new THREE.MeshStandardMaterial({map: texture})
  ];
  for(i = 0; i < 9; i++) {
    var box = new THREE.Mesh( geometry, materials );
    box.position.set(((i % 3) - 1) * 500, 0, Math.floor(i / 3) * 500);
    scene.add( box );
    boxies.push( box );
  }

  path = "./img/skybox";
  format = '.jpg';
  urls = [
    path + 'px' + format, path + 'nx' + format,
    path + 'py' + format, path + 'ny' + format,
    path + 'pz' + format, path + 'nz' + format
  ];

  tCube = new THREE.CubeTextureLoader().load( urls );
  scene.background = tCube;


  // DirectionalLight
  const light = new THREE.DirectionalLight(0xffffff);
  light.intensity = 2; //Double the light intensity
  light.position.set(1, 1, 1);
  // add scene
  scene.add(light);

  TMan.add();
  TMan.timer[0].setalerm(function() { Loop(0); }, 50);  //set main loop


  //main loop
  function Loop(id) {
    var i;
    for(i = 0; i < 9; i++) {
        boxies[i].rotation.x += 1.0 * Math.PI / 180.0;//Rotate 1 degree around the x axis
        boxies[i].rotation.y += 2.0 * Math.PI / 180.0;//Rotate 2 degree around the y axis
        boxies[i].rotation.z += 3.0 * Math.PI / 180.0;//Rotate 3 degree around the z axis
    }

    moveobj();

    // rendering
    renderer.render(scene, camera);

    TMan.timer[id].setalerm(function() { Loop(id); }, 50);  //set main loop
  }

}

//Object position information
//Position 4*4 matrix (continuous parameter)
var A = false;

//Speed ​​(continuation parameter)
var V = 0.1;
var a = 0;
var pyr = new N6LVector([1, 0, 0, 0], true); 
var la = new N6LVector(4, true).UnitVec(3); 
var up = new N6LVector(4, true).UnitVec(2); 

//After initializing as above, keep calling the function below

//Acceleration a, (scalar quantity) (new parameter)
//Pitch yaw roll (1, θp, θy, θr) (new parameter)
function moveobj() {

  if(!A) {
    var Proj = camera.projectionMatrix;
    A = new N6LVector([Proj.elements[15], Proj.elements[12], Proj.elements[13], Proj.elements[14]], true); 
  }

  var B = la.Mul(a);          //Camera translation row
  var az = new N6LVector(la); //Camera Z-axis row
  var ay = new N6LVector(up); //Camera Y-axis row
  var ax = az.Cross(ay);      //Camera X-axis row
  //Camera world matrix
  var matWK = new N6LMatrix([B,ax,ay,az]);
  matWK = matWK.NormalMat();

  //Yaw pitch roll rotation
  matWK = matWK.RotAxis(az, pyr.x[3] * -1.0);
  matWK = matWK.RotAxis(ay, pyr.x[2] * -1.0);
  matWK = matWK.RotAxis(ax, pyr.x[1] * -1.0);


  //update
  B = new N6LVector(matWK.x[0]);
  B = B.SetHomo(true);
  la = new N6LVector(matWK.x[3]);
  la = la.SetHomo(true);
  up = new N6LVector(matWK.x[2]);
  up = up.SetHomo(true);
  //C = camera position + camera Z axis + updated camera Z axis
  A = A.Add(B);
  var C = A.Add(la);
  //reset
  pyr = new N6LVector([1, 0, 0, 0], true); 

  //set up
  camera.position.set(A.x[1], A.x[2], A.x[3]);
  camera.up.set(up.x[1], up.x[2], up.x[3]);
  camera.lookAt(C.x[1], C.x[2], C.x[3]);
}


/*
function moveobj() {

  if(!A) {
    var Proj = camera.projectionMatrix;
    A = new N6LVector([Proj.elements[15], Proj.elements[12], Proj.elements[13], Proj.elements[14]], true); 
  }

  var B = la.Mul(a);          //Camera translation row
  var az = new N6LVector(la); //Camera Z-axis row
  var ay = new N6LVector(up); //Camera Y-axis row
  var ax = az.Cross(ay);      //Camera X-axis row

  B = B.RotAxis(az, pyr.x[3]);
  B = B.RotAxis(ay, pyr.x[2]);
  B = B.RotAxis(ax, pyr.x[1]);

  la = la.RotAxis(az, pyr.x[3]);
  la = la.RotAxis(ay, pyr.x[2]);
  la = la.RotAxis(ax, pyr.x[1]);

  up = up.RotAxis(az, pyr.x[3]);
  up = up.RotAxis(ay, pyr.x[2]);
  up = up.RotAxis(ax, pyr.x[1]);

  A = A.Add(B);

  var C = A.Add(la);


  pyr = new N6LVector([1, 0, 0, 0], true); 

  camera.position.set(A.x[1], A.x[2], A.x[3]);
  camera.up.set(up.x[1], up.x[2], up.x[3]);        // set up
  camera.lookAt(C.x[1], C.x[2], C.x[3]);

}
*/



//input keyboard
var KBLock7 = 0;
var KBLock9 = 0;
var KBIntvl = 5;
function chkKeyBoard(){
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N1'))]) {//N1Key
    pyr.x[3] -= 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N2'))]) {//N2Key
    pyr.x[1] += 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N3'))]) {//N3Key
    pyr.x[3] += 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N4'))]) {//N4Key
    pyr.x[2] += 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N5'))]) {//N5Key
    a = 0;
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N6'))]) {//N6Key
    pyr.x[2] -= 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N7'))]) {//N7Key
    if(KBIntvl < KBLock7) KBLock7 = 0;
    if(KBLock7 == 0) {
      a -= 0.5;
      if(a < -50) a = -50;
    }
    KBLock7++;
  }
  else KBLock7 = 0;
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N8'))]) {//N8Key
    pyr.x[1] -= 1 * (Math.PI / 180);
  }
  if(KeyB.keystate[KeyB.indexof(KeyB.ToReal('VK_N9'))]) {//N9Key
    if(KBIntvl < KBLock9) KBLock9 = 0;
    if(KBLock9 == 0) {
      a += 0.5;
      if(50 < a) a = 50;
    }
    KBLock9++;
  }
  else KBLock9 = 0;
};




Set up the skybox like this
The important thing is to set the file name clearly like
○○px,○○nx,○○py,○○ny,○○pz,○○nz,


path = "./img/skybox";
format = '.jpg';
urls = [
 path + 'px' + format, path + 'nx' + format,
 path + 'py' + format, path + 'ny' + format,
 path + 'pz' + format, path + 'nz' + format
];

tCube = new THREE.CubeTextureLoader().load( urls );
scene.background = tCube;

In the FPS part,

function moveobj(),

Camera position vector A,
LookAt vector la,
up vector up,
are stored globally,
var az = new N6LVector(la);
var ay = new N6LVector(up);
var ax = az.Cross(ay);
Find the local (camera) axis,
and rotate roll, yaw, and pitch on that axis,
You can calculate all at once with Matrix or individually with Vector,
Updated camera position upLookAt vector,
camera.position.set(A.x[1], A.x[2], A.x[3]);
camera.up.set(up.x[1], up.x[2], up.x[3]);
camera.lookAt(C.x[1], C.x[2], C.x[3]);
You can do this by setting




##############################

3D rotation test with X3DOM and ThreeJS


Detailed explanation of 3D rotation test using X3DOM and ThreeJS

3D rotation test with X3DOM

3D rotation test with ThreeJS

##############################




These samples are multifaceted numerical verifications of NAS6LIB's numerical calculations,
especially the rotation transformations of N6LVector, N6LMatrix, and N6LQuaternion.


Known issues ##############################

Overview

When converting 3D models between NAS6LIB X3DOM and ThreeJS, problems with left-right inversion of texture images
and transposition of view matrices occurred, especially in skyboxes.
View matrix transposition problem Even after solving the transposition problem,
the numerical calculations were performed correctly inside NAS6LIB, but when drawn in X3DOM,
it appeared as a mirror image. Since the problem worked fine in Three.js, it turned out that the cause was
a peculiar interpretation of the coordinate system in X3DOM,
which was resolved by adjusting the position of the texture and skybox.
Or rather, the reason there were no problems with ThreeJS may be because I hardly left any numerical calculations to it.

Problem

Left-right inversion and transposition phenomenon: When a matrix calculated in NAS6LIB was applied to X3DOM, the texture image, especially of the skybox,
was displayed with left-right inversion. The phenomenon of transposition of the view matrix was also confirmed.
Coordinate system differences between libraries: NAS6LIB is a left-handed coordinate system, but X3DOM is based on a right-handed system,
so the conversion was complicated.
Comparison with Three.js: Since no problems occurred with the same conversion logic in Three.js, it was found that this was a special problem caused by the interpretation of the coordinate system in X3DOM.

Solution

Adjusting N6LMatrix.FromX3DOM(): The transposition problem was solved by applying a transposition to the return value.
Flip the skybox image left and right and adjust placement: Since matrix transformation did not entirely solve the problem,
the image used for the skybox was flipped left and right (mirrored) using an image editing software.
At the same time, the placement of the images for the **front and back faces** (corresponding to the Z-axis direction)
in X3DOM's Background node was also adjusted. This combination finally achieved the correct display.

Learned

Library-specific coordinate system interpretation: Since each 3D library has its own coordinate system definition and rendering pipeline,
when linking different libraries,it is important to understand the characteristics of each library and adjus
t the placement of textures and objects as necessary to avoid visual differences, not just numerical accuracy.

Debugging strategy: When problems are complicated and intertwined, it is effective to first check the simplest "no rotation" state,
and then verify the behavior with a simple test case such as a single-axis rotation.

Consider practical solutions: When mathematical transformations are complicated and difficult to solve, approaches
that solve visual problems more directly, such as adjusting textures, can also be effective.

##############################





 ■■■ ./nas6lib/keyboard.js memo ■■■ 

keyID、keycode fig.

realID、U.S. standard keyboard

0xYX

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

0x0X

VK_$00

VK_LBUTTON

VK_RBUTTON

VK_CANCEL : Break

VK_MBUTTON

VK_XBUTTON1

VK_XBUTTON2

VK_$07

VK_BACK : BackSpace

VK_TAB : Tab

VK_$0A

VK_$0B

VK_CLEAR

VK_RETURN : Enter

VK_$0E

VK_$0F

0x1X

VK_SHIFT : Shift

VK_CONTROL : Ctrl

VK_MENU : Alt

VK_PAUSE

VK_CAPITAL

VK_KANA

VK_$16

VK_JUNJA

VK_FINAL

VK_KANJI

VK_$1A

VK_ESCAPE : Esc

VK_CONVERT : 変換

VK_NONCONVERT : 無変換

VK_ACCEPT

VK_MODCHANGE

0x2X

VK_SPACE : Space

VK_PRIOR : PgUp

VK_NEXT : PgDn

VK_END : End

VK_HOME : Home

VK_LEFT : ←

VK_UP : ↑

VK_RIGHT : →

VK_DOWN : ↓

VK_SELECT

VK_PRINT

VK_EXECUTE

VK_SNAPSHOT : Print Screen

VK_INSERT : Ins

VK_DELETE : Del

VK_HELP

0x3X

VK_0

VK_1

VK_2

VK_3

VK_4

VK_5

VK_6

VK_7

VK_8

VK_9

VK_$3A

VK_$3B

VK_$3C

VK_$3D

VK_$3E

VK_$3F

0x4X

VK_$40

VK_A

VK_B

VK_C

VK_D

VK_E

VK_F

VK_G

VK_H

VK_I

VK_J

VK_K

VK_L

VK_M

VK_N

VK_O

0x5X

VK_P

VK_Q

VK_R

VK_S

VK_T

VK_U

VK_V

VK_W

VK_X

VK_Y

VK_Z

VK_LWIN

VK_RWIN

VK_APPS

VK_$5E

VK_SLEEP

0x6X

VK_NUMPAD0

VK_NUMPAD1

VK_NUMPAD2

VK_NUMPAD3

VK_NUMPAD4

VK_NUMPAD5

VK_NUMPAD6

VK_NUMPAD7

VK_NUMPAD8

VK_NUMPAD9

VK_MULTIPLY : numpad *

VK_ADD : numpad +

VK_SEPARATOR : numpad enter

VK_SUBTRACT : numpad -

VK_DECIMAL : numpad .

VK_DIVIDE : numpad /

0x7X

VK_F1

VK_F2

VK_F3

VK_F4

VK_F5

VK_F6

VK_F7

VK_F8

VK_F9

VK_F10

VK_F11

VK_F12

VK_F13

VK_F14

VK_F15

VK_F16

0x8X

VK_F17

VK_F18

VK_F19

VK_F20

VK_F21

VK_F22

VK_F23

VK_F24

VK_$88

VK_$89

VK_$8A

VK_$8B

VK_$8C

VK_$8D

VK_$8E

VK_$8F

0x9X

VK_NUMLOCK : Num Lock

VK_SCROLL : Scroll Lock

VK_$92

VK_$93

VK_$94

VK_$95

VK_$96

VK_$97

VK_$98

VK_$99

VK_$9A

VK_$9B

VK_$9C

VK_$9D

VK_$9E

VK_$9F

0xAX

VK_LSHIFT

VK_RSHIFT

VK_LCONTROL

VK_RCONTROL

VK_LMENU

VK_RMENU

VK_BROWSER_BACK

VK_BROWSER_FORWARD

VK_BROWSER_REFRESH

VK_BROWSER_STOP

VK_BROWSER_SERCH

VK_BROWSER_FAVORITES

VK_BROWSER_HOME

VK_VOLUME_MUTE

VK_VOLUME_DOWN

VK_VOLUME_UP

0xBX

VK_MEDIA_NEXT_TRACK

VK_MEDIA_PREV_TRACK

VK_MEDIA_STOP

VK_MEDIA_PLAY_PAUSE

VK_LAUNCH_MAIL

VK_LAUNCH_MEDIA_SELECT

VK_LAUNCH_APP1

VK_LAUNCH_APP2

VK_$B8

VK_$B9

VK_OEM_1 : [:;]

VK_OEM_PLUS : [+]

VK_OEM_COMMA : [,]

VK_OEM_MINUS : [-]

VK_OEM_PERIOD : [.]

VK_OEM_2 : [/?]

0xCX

VK_OEM_3 : [`~]

VK_$C1

VK_$C2

VK_$C3

VK_$C4

VK_$C5

VK_$C6

VK_$C7

VK_$C8

VK_$C9

VK_$CA

VK_$CB

VK_$CC

VK_$CD

VK_$CE

VK_$CF

0xDX

VK_$D0

VK_$D1

VK_$D2

VK_$D3

VK_$D4

VK_$D5

VK_$D6

VK_$D7

VK_$D8

VK_$D9

VK_$DA

VK_OEM_4 : [[{]

VK_OEM_5 : [\|]

VK_OEM_6 : []}]

VK_OEM_7 : [']

VK_OEM_8

0xEX

VK_$E0

VK_OEM_AX

VK_OEM_102 : [\_]

VK_ICO_HELP

VK_ICO_00

VK_PROCESSKEY

VK_ICO_CLEAR

VK_PACKET

VK_$E8

VK_OEM_RESET

VK_OEM_JUMP

VK_OEM_PA1

VK_OEM_PA2

VK_OEM_PA3

VK_OEM_WSCTRL

VK_OEM_CUSEL

0xFX

VK_OEM_ATTN

VK_OEM_FINISH

VK_OEM_COPY

VK_OEM_AUTO

VK_OEM_ENLW

VK_OEM_BACKTAB

VK_ATTN

VK_CRSEL

VK_EXSEL

VK_EREOF

VK_PLAY

VK_ZOOM

VK_NONAME

VK_PA1

VK_OEM_CLEAR

VK_$FF


realID, aliasID

VK_RETURN, VK_ENTER

VK_ESCAPE, VK_ESC

VK_OEM_MINUS, VK_-

VK_OEM_7, VK_^

VK_NUMPAD1, VK_N1

VK_NUMPAD2, VK_N2

VK_NUMPAD3, VK_N3

VK_NUMPAD4, VK_N4

VK_NUMPAD5, VK_N5

VK_NUMPAD6, VK_N6

VK_NUMPAD7, VK_N7

VK_NUMPAD8, VK_N8

VK_NUMPAD9, VK_N9

VK_NUMPAD0, VK_N0

VK_DECIMAL, VK_N.

VK_ADD, VK_N+

VK_SUBTRACT, VK_N-

VK_MULTIPLY, VK_N*

VK_DIVIDE, VK_N/

VK_NUMLOCK, VK_NLK

VK_OEM_5, VK_|

VK_OEM_3, VK_@

VK_OEM_4, VK_[

VK_OEM_PLUS, VK_;

VK_OEM_1, VK_:

VK_OEM_6, VK_]

VK_OEM_COMMA, VK_,

VK_OEM_PERIOD, VK_.

VK_OEM_2, VK_/

VK_OEM_102, VK__

VK_CONTROL, VK_CTRL

VK_MENU, VK_ALT

VK_CONVERT, VK_CNVT

VK_NONCONVERT, VK_NONCNVT

VK_PRIOR, VK_PGUP

VK_NEXT, VK_PGDN

VK_LEFT, VK_←

VK_UP, VK_↑

VK_RIGHT, VK_→

VK_DOWN, VK_↓

VK_INSERT, VK_INS

VK_DELETE, VK_DEL

VK_SCROLL, VK_SLK

VK_SNAPSHOT, VK_PRTSCRN

VK_OEM_ATTN, VK_CLK

VK_OEM_COPY, VK_KANA

VK_OEM_ENLW, VK_ZEN

VK_OEM_AUTO, VK_ZEN2

VK_PAUSE, VK_BRK

VK_CLEAR, VK_CLS

---

---

---

---

---

---


Interconversion of real name ID and alias ID can KeyB.ToRealID(str) and KeyB.ToAliasID(str, ary){alias list has been returned to the array ary}.
You can determine depression of the keyboard in if(KeyB.keystate[KeyB.indexof(KeyB.ToRealID(str))]).
Alias additional definition in KeyB.addAlias([srcIDstr, destIDstr]).
Delete together also tying the alias KeyB.delAlias(str).
KeyB.UnityAlias(aliasID) is unity alias name.
KeyB.isPressUnityAlias(aliasID) is press info unity alias.
It can handle more than one key as one of the key in the unity-related

■NAS6LIB Help Document■


//######## N6LTimerMan ########
//./javascripts/nas6lib/timer.js
//######## timer manager ########

N6LTimerMan:construction

N6LTimerMan.add()
N6LTimerMan.changeinterval(int)
N6LTimerMan.start()
N6LTimerMan.stop()

//######## N6LTimerMan.timer[id] ########
//./javascripts/nas6lib/timer.js
//######## timer ########
//id:timer id

N6LTimerMan.timer[id].start()
N6LTimerMan.timer[id].stop()
N6LTimerMan.timer[id].reset()
N6LTimerMan.timer[id].copy(src)
N6LTimerMan.timer[id].now()
N6LTimerMan.timer[id].setalerm(func(id),alm)

//######## N6LVector ########
//./javascripts/nas6lib/vector.js
//######## vector ########

N6LVector:construction

N6LVector.Equal(rh)
N6LVector.EpsEqual(rh, eps)
N6LVector.Str()
N6LVector.Parse(str)
N6LVector.ToX3DOM(b)
N6LVector.FromX3DOM(sf)
N6LVector.To3JS(b)
N6LVector.From3JS(ary)
N6LVector.Add(rh)
N6LVector.Sub(rh)
N6LVector.Mul(rh)
N6LVector.Div(rh)
N6LVector.SetHomo(rh)
N6LVector.Repair(eps)
N6LVector.Dot(rh)
N6LVector.Cross(rh)
N6LVector.isParallel()
N6LVector.Max()
N6LVector.DivMax()
N6LVector.LookAtMat2(rh)
N6LVector.RotArcQuat(rh)
N6LVector.ZeroVec()
N6LVector.UnitVec(a)
N6LVector.NormalVec(a)
N6LVector.SquareAbs()
N6LVector.Abs()
N6LVector.DirectionCosine()
N6LVector.Theta(rh)
N6LVector.ThetaN(rh)
N6LVector.Rot2D(theta)
N6LVector.RotAxis(axis, theta)
N6LVector.RotAxisQuat(axis, theta)
N6LVector.RotAxisVec(rotvec)
N6LVector.ProjectAxis(axis)
N6LVector.DistanceDotLine(p, a, b)
N6LVector.DistancePointLineLine(reta, retb, a0, a1, b0, b1)
N6LVector.PointLineLine(reta, retb, a0, a1, b0, b1)
N6LVector.DistanceLineLine(a0, a1, b0, b1)
N6LVector.Homogeneous()
N6LVector.ToHomo()
N6LVector.ToNormal()
N6LVector.Matrix()
N6LVector.PosVecGetTQ(out)
N6LVector.PosVecSetTQ(t,q)
N6LVector.PosVecMatrix()
N6LVector.PosVecMul(rh)
N6LVector.Sphere4D()
N6LVector.FromLogAxis(base, range, x)
N6LVector.ToLogAxis(base, range, x)
N6LVector.FrustumInfVec(base, range, v)
N6LVector.InvFrustumInfVec(base, range, v, z)

//######## N6LMatrix ########
//./javascripts/nas6lib/matrix.js
//######## matrix ########

N6LMatrix:construction

N6LMatrix.Equal(rh)
N6LMatrix.EpsEqual(rh, eps)
N6LMatrix.Str()
N6LMatrix.Parse(str)
N6LMatrix.ToX3DOM()
N6LMatrix.FromX3DOM(sf)
N6LMatrix.To3JS()
N6LMatrix.From3JS(ary)
N6LMatrix.GetCol(rh)
N6LMatrix.GetRow(rh)
N6LMatrix.SetCol(rh, val)
N6LMatrix.SetRow(rh, val)
N6LMatrix.Add(rh)
N6LMatrix.Sub(rh)
N6LMatrix.Mul(rh)
N6LMatrix.Div(rh)
N6LMatrix.SetHomo(rh)
N6LMatrix.Repair(eps)
N6LMatrix.Max()
N6LMatrix.DivMax()
N6LMatrix.ZeroMat()
N6LMatrix.UnitMat()
N6LMatrix.NormalMat()
N6LMatrix.TransposedMat()
N6LMatrix.TranslatedMat(rh)
N6LMatrix.ScaleMat(rh)
N6LMatrix.AffineMat(scale, rotate, translate)
N6LMatrix.MoveMat(outmat, outv, d, pyr, v, a, vmin, vmax)
N6LMatrix.LookAtMat(eye, lookat, up)
N6LMatrix.LookAtMat2(rh)
N6LMatrix.InverseMat(dt, sw)
N6LMatrix.InverseMat00(dt)
N6LMatrix.InverseMat01(dt)
N6LMatrix.DeterminMatInvMat(dt)
N6LMatrix.DeterminMat(dt)
N6LMatrix.Jacobi(n, ct, eps, A, A1, A2, X1, X2)
N6LMatrix.EigenVec(ct, eps, A, det, eigen)
N6LMatrix.DiagonalMat(ct, eps)
N6LMatrix.Diagonal(ct, eps)
N6LMatrix.Rot2D(theta)
N6LMatrix.RotAxis(axis, theta)
N6LMatrix.RotAxisQuat(axis, theta)
N6LMatrix.RotAxisVec(rotvec)
N6LMatrix.Homogeneous()
N6LMatrix.ToHomo()
N6LMatrix.ToNormal()
N6LMatrix.Pos()
N6LMatrix.Scale()
N6LMatrix.Trace()
N6LMatrix.Quaternion()
N6LMatrix.Vector()
N6LMatrix.PosVector()
N6LMatrix.FrustumMat(left, right, top, bottom, near, far)
N6LMatrix.OrthoMat(left, right, top, bottom, near, far)
N6LMatrix.Householder()
N6LMatrix.QRMethod()
N6LMatrix.EulerAngle(first, second, third, eps)

//######## N6LQuaternion ########
//./javascripts/nas6lib/quaternion.js
//######## Quaternion ########

N6LQuaternion:construction

N6LQuaternion.Equal(rh)
N6LQuaternion.EpsEqual(rh, eps)
N6LQuaternion.Str()
N6LQuaternion.Parse(str)
N6LQuaternion.Add(rh)
N6LQuaternion.Sub(rh)
N6LQuaternion.Mul(rh)
N6LQuaternion.Div(rh)
N6LQuaternion.DivMax()
N6LQuaternion.Repair(eps)
N6LQuaternion.SquareAbs()
N6LQuaternion.Abs()
N6LQuaternion.ConjugationQuat()
N6LQuaternion.InverseQuat()
N6LQuaternion.ZeroQuat()
N6LQuaternion.UnitQuat()
N6LQuaternion.NormalQuat()
N6LQuaternion.Dot(rh)
N6LQuaternion.RotAxisQuat(axis, theta)
N6LQuaternion.RotAxisVec(rotvec)
N6LQuaternion.Axis(axis, theta)
N6LQuaternion.Matrix()
N6LQuaternion.Lerp(q, t)
N6LQuaternion.Slerp(q, t)
N6LQuaternion.Slerp2(q, t)
N6LQuaternion.Sphere4D()

//######## N6LLnQuaternion ########
//./javascripts/nas6lib/quaternion.js
//######## logarithm quaternion ########

N6LLnQuaternion:construction

N6LLnQuaternion.Equal(rh)
N6LLnQuaternion.EpsEqual(rh, eps)
N6LLnQuaternion.Str()
N6LLnQuaternion.Parse(str)
N6LLnQuaternion.Add(rh)
N6LLnQuaternion.Sub(rh)
N6LLnQuaternion.Mul(rh)
N6LLnQuaternion.Div(rh)
N6LLnQuaternion.DivMax()
N6LLnQuaternion.Repair(eps)
N6LLnQuaternion.SquareAbs()
N6LLnQuaternion.Abs()
N6LLnQuaternion.ZeroLnQuat()
N6LLnQuaternion.RotAxisLnQuat(axis, theta)
N6LLnQuaternion.Axis(axis, theta)
N6LLnQuaternion.Lerp(q, t)
N6LLnQuaternion.Lerp2(d0, q, d)

//######## N6LKeyBoard ########
//./javascripts/nas6lib/keyboard.js
//######## KeyBoard ########

N6LKeyBoard:construction

N6LKeyBoard.setfunc(func)
N6LKeyBoard.setenable(b)
N6LKeyBoard.indexof(str)
N6LKeyBoard.addAlias(ary)
N6LKeyBoard.delAlias(str)
N6LKeyBoard.addUnityAlias(ary)
N6LKeyBoard.delUnityAlias(str)
N6LKeyBoard.UnityAlias(str)
N6LKeyBoard.isPressUnityAlias(str)
N6LKeyBoard.ToAlias(str, ret)
N6LKeyBoard.ToReal(str)