ModelHandle/test/tests/model_test.js

462 lines
17 KiB
JavaScript

import * as assert from 'assert';
import * as OV from '../../source/engine/main.js';
import { GetHierarchicalModelNoFinalization, GetTranslatedRotatedCubesModel, ModelNodesToTree } from '../utils/testutils.js';
export default function suite ()
{
describe ('Model', function () {
it ('Default Initialization', function () {
var model = new OV.Model ();
assert.strictEqual (model.MaterialCount (), 0);
assert.strictEqual (model.MeshCount (), 0);
});
it ('Add Material', function () {
var model = new OV.Model ();
var material = new OV.PhongMaterial ();
material.name = 'example';
var index = model.AddMaterial (material);
assert.strictEqual (model.MaterialCount (), 1);
var theMaterial = model.GetMaterial (index);
assert.strictEqual (theMaterial.name, 'example');
});
it ('Add Mesh', function () {
var model = new OV.Model ();
var mesh = new OV.Mesh ();
mesh.SetName ('example');
var index = model.AddMesh (mesh);
assert.strictEqual (model.MeshCount (), 1);
var theMesh = model.GetMesh (index);
assert.strictEqual (theMesh.GetName (), 'example');
});
it ('Counters', function () {
var model = new OV.Model ();
let mesh = new OV.Mesh ();
mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddNormal (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddNormal (new OV.Coord3D (0.0, 0.0, 0.0));
mesh.AddTextureUV (new OV.Coord2D (0.0, 0.0));
mesh.AddLine (new OV.Line ([0, 1]));
mesh.AddLine (new OV.Line ([1, 2]));
mesh.AddLine (new OV.Line ([2, 0]));
mesh.AddTriangle (new OV.Triangle (0, 1, 2));
mesh.AddTriangle (new OV.Triangle (0, 1, 2));
mesh.AddTriangle (new OV.Triangle (0, 1, 2));
mesh.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMeshToRootNode (mesh);
assert.strictEqual (model.VertexCount (), 3);
assert.strictEqual (model.NormalCount (), 2);
assert.strictEqual (model.TextureUVCount (), 1);
assert.strictEqual (model.LineCount (), 3);
assert.strictEqual (model.TriangleCount (), 4);
});
it ('Remove Mesh', function () {
var model = new OV.Model ();
let mesh1 = new OV.Mesh ();
mesh1.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
mesh1.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
mesh1.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh1.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMeshToRootNode (mesh1);
let mesh2 = new OV.Mesh ();
mesh2.AddVertex (new OV.Coord3D (0.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 0.0, 1.0));
mesh2.AddVertex (new OV.Coord3D (1.0, 1.0, 1.0));
mesh2.AddTriangle (new OV.Triangle (0, 1, 2));
model.AddMeshToRootNode (mesh2);
assert.strictEqual (model.MeshCount (), 2);
assert.strictEqual (model.VertexCount (), 6);
assert.strictEqual (model.TriangleCount (), 2);
model.RemoveMesh (0);
assert.strictEqual (model.MeshCount (), 1);
assert.strictEqual (model.VertexCount (), 3);
assert.strictEqual (model.TriangleCount (), 1);
model.RemoveMesh (0);
assert.strictEqual (model.MeshCount (), 0);
assert.strictEqual (model.VertexCount (), 0);
assert.strictEqual (model.TriangleCount (), 0);
});
});
describe ('Model Finalization', function () {
it ('Create Default Material', function () {
var mesh = new OV.Mesh ();
var v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
var v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
var v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
var v3 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh.AddLine (new OV.Line ([v0, v1]));
mesh.AddLine (new OV.Line ([v1, v2]));
mesh.AddTriangle (new OV.Triangle (v0, v1, v2));
mesh.AddTriangle (new OV.Triangle (v0, v2, v3));
var model = new OV.Model ();
model.AddMesh (mesh);
OV.FinalizeModel (model, {
defaultLineMaterialColor : new OV.RGBColor (1, 2, 3),
defaultMaterialColor : new OV.RGBColor (4, 5, 6)
});
assert.strictEqual (model.MaterialCount (), 2);
assert.deepStrictEqual (model.GetMaterial (0).color, new OV.RGBColor (1, 2, 3));
assert.deepStrictEqual (model.GetMaterial (1).color, new OV.RGBColor (4, 5, 6));
});
it ('Calculate Normal', function () {
var mesh = new OV.Mesh ();
var v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
var v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
var v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
var triangleIndex = mesh.AddTriangle (new OV.Triangle (v0, v1, v2));
var model = new OV.Model ();
var meshIndex = model.AddMesh (mesh);
assert.strictEqual (model.MaterialCount (), 0);
OV.FinalizeModel (model);
assert.strictEqual (model.MaterialCount (), 1);
var theMesh = model.GetMesh (meshIndex);
assert.strictEqual (theMesh.NormalCount (), 1);
var triangle = theMesh.GetTriangle (triangleIndex);
assert.strictEqual (triangle.n0, 0);
assert.strictEqual (triangle.n1, 0);
assert.strictEqual (triangle.n2, 0);
assert.strictEqual (triangle.mat, 0);
});
it ('Calculate Curved Normal', function () {
var mesh = new OV.Mesh ();
var v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
var v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
var v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
var v3 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, -1.0));
var triangle1 = new OV.Triangle (v0, v1, v2);
triangle1.curve = 1;
var triangle2 = new OV.Triangle (v0, v3, v1);
triangle2.curve = 1;
var triangle1 = mesh.AddTriangle (triangle1);
var triangle1 = mesh.AddTriangle (triangle2);
var model = new OV.Model ()
var meshIndex = model.AddMesh (mesh);
OV.FinalizeModel (model);
var theMesh = model.GetMesh (meshIndex);
assert.strictEqual (theMesh.NormalCount (), 6);
var normal = theMesh.GetNormal (0);
assert.strictEqual (normal.x, 0.0);
assert.strictEqual (normal.y, -0.7071067811865475);
assert.strictEqual (normal.z, 0.7071067811865475);
});
it ('Calculate Curved Normal 2', function () {
var mesh = new OV.Mesh ();
var v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
var v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
var v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
var v3 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, -1.0));
var v4 = mesh.AddVertex (new OV.Coord3D (0.0, 1.0, 0.0));
var triangle1 = new OV.Triangle (v0, v1, v2);
triangle1.curve = 1;
var triangle2 = new OV.Triangle (v0, v2, v4);
triangle2.curve = 1;
var triangle3 = new OV.Triangle (v0, v3, v1);
triangle3.curve = 1;
mesh.AddTriangle (triangle1);
mesh.AddTriangle (triangle2);
mesh.AddTriangle (triangle3);
var model = new OV.Model ()
var meshIndex = model.AddMesh (mesh);
OV.FinalizeModel (model);
var theMesh = model.GetMesh (meshIndex);
assert.strictEqual (theMesh.NormalCount (), 9);
var normal = theMesh.GetNormal (0);
assert.strictEqual (normal.x, 0.0);
assert.strictEqual (normal.y, -0.7071067811865475);
assert.strictEqual (normal.z, 0.7071067811865475);
});
it ('Remove Empty Meshes and Nodes', function () {
let mesh = new OV.Mesh ();
let emptyMesh = new OV.Mesh ();
let v0 = mesh.AddVertex (new OV.Coord3D (0.0, 0.0, 0.0));
let v1 = mesh.AddVertex (new OV.Coord3D (1.0, 0.0, 0.0));
let v2 = mesh.AddVertex (new OV.Coord3D (1.0, 1.0, 0.0));
mesh.AddTriangle (new OV.Triangle (v0, v1, v2));
let model = new OV.Model ()
let meshIndex = model.AddMesh (mesh);
let emptyMeshIndex = model.AddMesh (emptyMesh);
let rootNode = model.GetRootNode ();
let node1 = new OV.Node ();
rootNode.AddChildNode (node1);
node1.AddMeshIndex (meshIndex);
node1.AddMeshIndex (emptyMeshIndex);
let node2 = new OV.Node ();
rootNode.AddChildNode (node2);
let node3 = new OV.Node ();
rootNode.AddChildNode (node3);
node3.AddMeshIndex (meshIndex);
node3.AddMeshIndex (emptyMeshIndex);
OV.FinalizeModel (model);
assert.strictEqual (model.MeshCount (), 1);
let meshInstances = [];
model.EnumerateMeshInstances ((meshInstance) => {
meshInstances.push (meshInstance);
});
assert.strictEqual (meshInstances.length, 2);
let nodeCount = 0;
rootNode.Enumerate ((node) => {
nodeCount += 1;
});
assert.strictEqual (nodeCount, 3);
});
it ('Remove Empty Nodes Recursively', function () {
let model = GetHierarchicalModelNoFinalization ();
OV.FinalizeModel (model);
assert.strictEqual (model.MeshCount (), 0);
assert.strictEqual (model.MeshInstanceCount (), 0);
assert.ok (model.GetRootNode ().IsEmpty ());
});
});
describe ('Color Conversion', function () {
it ('Color equality check', function () {
assert.ok (OV.RGBColorIsEqual (new OV.RGBColor (10, 20, 30), new OV.RGBColor (10, 20, 30)));
assert.ok (!OV.RGBColorIsEqual (new OV.RGBColor (10, 20, 30), new OV.RGBColor (11, 20, 30)));
assert.ok (!OV.RGBColorIsEqual (new OV.RGBColor (10, 20, 30), new OV.RGBColor (10, 21, 30)));
assert.ok (!OV.RGBColorIsEqual (new OV.RGBColor (10, 20, 30), new OV.RGBColor (10, 20, 31)));
});
it ('RGB Color hex string conversion', function () {
let color = new OV.RGBColor (10, 20, 30);
let hexString = '0a141e';
assert.strictEqual (OV.RGBColorToHexString (color), hexString);
assert.deepStrictEqual (OV.HexStringToRGBColor (hexString), color);
});
it ('RGBA Color hex string conversion', function () {
let color = new OV.RGBAColor (10, 20, 30, 40);
let hexString = '0a141e28';
assert.strictEqual (OV.RGBAColorToHexString (color), hexString);
assert.deepStrictEqual (OV.HexStringToRGBAColor (hexString), color);
let color2 = new OV.RGBAColor (10, 20, 30, 255);
let hexString2 = '0a141e';
let hexString2a = '0a141eff';
assert.strictEqual (OV.RGBAColorToHexString (color2), hexString2a);
assert.deepStrictEqual (OV.HexStringToRGBAColor (hexString2), color2);
});
});
describe ('Node Hierarchy', function () {
it ('Enumerate hierarchy', function () {
let model = GetHierarchicalModelNoFinalization ();
let modelTree = ModelNodesToTree (model);
assert.deepStrictEqual (modelTree, {
name : '<Root>',
childNodes : [
{
name : 'Node 1',
childNodes : [
{
name : 'Node 3',
childNodes : [],
meshNames : ['Mesh 5', 'Mesh 6', 'Mesh 7']
},
{
name : 'Node 4',
childNodes : [],
meshNames : ['Mesh 7']
}
],
meshNames : ['Mesh 3', 'Mesh 4']
},
{
name : 'Node 2',
childNodes : [],
meshNames : []
}
],
meshNames : ['Mesh 1', 'Mesh 2']
});
});
it ('Remove mesh', function () {
let model = GetHierarchicalModelNoFinalization ();
model.RemoveMesh (2);
let modelTree = ModelNodesToTree (model);
assert.deepStrictEqual (modelTree, {
name : '<Root>',
childNodes : [
{
name : 'Node 1',
childNodes : [
{
name : 'Node 3',
childNodes : [],
meshNames : ['Mesh 5', 'Mesh 6', 'Mesh 7']
},
{
name : 'Node 4',
childNodes : [],
meshNames : ['Mesh 7']
}
],
meshNames : ['Mesh 4']
},
{
name : 'Node 2',
childNodes : [],
meshNames : []
}
],
meshNames : ['Mesh 1', 'Mesh 2']
});
});
it ('Enumerate mesh instances', function () {
let model = GetTranslatedRotatedCubesModel ();
let modelTree = ModelNodesToTree (model);
assert.deepStrictEqual (modelTree, {
name : '<Root>',
childNodes : [
{
name : 'Translated',
childNodes : [],
meshNames : ['Cube']
},
{
name : 'Rotated',
childNodes : [
{
name : 'Translated and Rotated',
childNodes : [],
meshNames : ['Cube']
}
],
meshNames : []
}
],
meshNames : ['Cube']
});
let meshInstances = [];
model.EnumerateMeshInstances ((meshInstance) => {
meshInstances.push (meshInstance);
});
assert.strictEqual (meshInstances.length, 3);
let boundingBox1 = OV.GetBoundingBox (meshInstances[0]);
let boundingBox2 = OV.GetBoundingBox (meshInstances[1]);
let boundingBox3 = OV.GetBoundingBox (meshInstances[2]);
assert.ok (OV.CoordIsEqual3D (boundingBox1.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox1.max, new OV.Coord3D (1.0, 1.0, 1.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox2.min, new OV.Coord3D (2.0, 0.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox2.max, new OV.Coord3D (3.0, 1.0, 1.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox3.min, new OV.Coord3D (-1.0, 2.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox3.max, new OV.Coord3D (0.0, 3.0, 1.0)));
});
it ('Enumerate transformed mesh instances', function () {
let model = GetTranslatedRotatedCubesModel ();
let modelTree = ModelNodesToTree (model);
assert.deepStrictEqual (modelTree, {
name : '<Root>',
childNodes : [
{
name : 'Translated',
childNodes : [],
meshNames : ['Cube']
},
{
name : 'Rotated',
childNodes : [
{
name : 'Translated and Rotated',
childNodes : [],
meshNames : ['Cube']
}
],
meshNames : []
}
],
meshNames : ['Cube']
});
let meshes = [];
model.EnumerateTransformedMeshInstances ((mesh) => {
meshes.push (mesh);
});
assert.strictEqual (meshes.length, 3);
let boundingBox1 = OV.GetBoundingBox (meshes[0]);
let boundingBox2 = OV.GetBoundingBox (meshes[1]);
let boundingBox3 = OV.GetBoundingBox (meshes[2]);
assert.ok (OV.CoordIsEqual3D (boundingBox1.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox1.max, new OV.Coord3D (1.0, 1.0, 1.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox2.min, new OV.Coord3D (2.0, 0.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox2.max, new OV.Coord3D (3.0, 1.0, 1.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox3.min, new OV.Coord3D (-1.0, 2.0, 0.0)));
assert.ok (OV.CoordIsEqual3D (boundingBox3.max, new OV.Coord3D (0.0, 3.0, 1.0)));
});
it ('Instance counters', function () {
let model = GetTranslatedRotatedCubesModel ();
OV.FinalizeModel (model);
assert.strictEqual (model.MeshCount (), 1);
assert.strictEqual (model.MeshInstanceCount (), 3);
assert.strictEqual (model.VertexCount (), 8 * 3);
assert.strictEqual (model.NormalCount (), 12 * 3);
assert.strictEqual (model.TextureUVCount (), 0);
assert.strictEqual (model.TriangleCount (), 12 * 3);
});
it ('Instance enumeration', function () {
let model = GetTranslatedRotatedCubesModel ();
let meshInstances = [];
model.EnumerateMeshInstances ((meshInstance) => {
meshInstances.push (meshInstance);
});
assert.ok (meshInstances[0].GetId ().IsEqual (new OV.MeshInstanceId (0, 0)));
assert.ok (meshInstances[1].GetId ().IsEqual (new OV.MeshInstanceId (1, 0)));
assert.ok (meshInstances[2].GetId ().IsEqual (new OV.MeshInstanceId (3, 0)));
});
});
}