196 lines
7.3 KiB
JavaScript
196 lines
7.3 KiB
JavaScript
import { ValueOrDefault } from '../core/core.js';
|
|
import { ArrayToCoord3D, Coord3D } from '../geometry/coord3d.js';
|
|
import { Direction } from '../geometry/geometry.js';
|
|
import { Matrix } from '../geometry/matrix.js';
|
|
import { ArrayToQuaternion, Quaternion } from '../geometry/quaternion.js';
|
|
import { Transformation } from '../geometry/transformation.js';
|
|
import { ArrayBufferToUtf8String } from '../io/bufferutils.js';
|
|
import { ArrayToRGBColor } from '../model/color.js';
|
|
import { GenerateCone, GenerateCuboid, GenerateCylinder, GeneratePlatonicSolid, GenerateSphere, GeneratorParams } from '../model/generator.js';
|
|
import { PhysicalMaterial } from '../model/material.js';
|
|
import { Node, NodeType } from '../model/node.js';
|
|
import { Property, PropertyGroup, PropertyType } from '../model/property.js';
|
|
import { ImporterBase } from './importerbase.js';
|
|
|
|
export class ImporterO3dv extends ImporterBase
|
|
{
|
|
constructor ()
|
|
{
|
|
super ();
|
|
}
|
|
|
|
CanImportExtension (extension)
|
|
{
|
|
return extension === 'o3dv';
|
|
}
|
|
|
|
GetUpDirection ()
|
|
{
|
|
return Direction.Z;
|
|
}
|
|
|
|
ClearContent ()
|
|
{
|
|
|
|
}
|
|
|
|
ResetContent ()
|
|
{
|
|
|
|
}
|
|
|
|
ImportContent (fileContent, onFinish)
|
|
{
|
|
let textContent = ArrayBufferToUtf8String (fileContent);
|
|
let content = JSON.parse (textContent);
|
|
if (content.root === undefined) {
|
|
onFinish ();
|
|
return;
|
|
}
|
|
|
|
if (content.materials !== undefined) {
|
|
for (let i = 0; i < content.materials.length; i++) {
|
|
const materialContent = content.materials[i];
|
|
this.ImportMaterial (materialContent);
|
|
}
|
|
}
|
|
if (content.meshes !== undefined) {
|
|
for (let i = 0; i < content.meshes.length; i++) {
|
|
const meshContent = content.meshes[i];
|
|
this.ImportMesh (meshContent);
|
|
}
|
|
}
|
|
|
|
let rootNode = content.nodes[content.root];
|
|
this.ImportNode (content, rootNode, this.model.GetRootNode ());
|
|
this.ImportProperties (this.model, content);
|
|
|
|
onFinish ();
|
|
}
|
|
|
|
ImportMaterial (materialContent)
|
|
{
|
|
let material = new PhysicalMaterial ();
|
|
material.color.Set (255, 255, 255);
|
|
if (materialContent.name !== undefined) {
|
|
material.name = materialContent.name;
|
|
}
|
|
if (materialContent.color !== undefined) {
|
|
material.color = ArrayToRGBColor (materialContent.color);
|
|
}
|
|
material.metalness = ValueOrDefault (materialContent.metalness, 0.0);
|
|
material.roughness = ValueOrDefault (materialContent.roughness, 1.0);
|
|
this.model.AddMaterial (material);
|
|
}
|
|
|
|
ImportMesh (meshContent)
|
|
{
|
|
let genParams = new GeneratorParams ();
|
|
if (meshContent.name !== undefined) {
|
|
genParams.SetName (meshContent.name);
|
|
}
|
|
if (meshContent.material !== undefined) {
|
|
genParams.SetMaterial (meshContent.material);
|
|
}
|
|
|
|
let parameters = meshContent.parameters;
|
|
if (parameters === undefined) {
|
|
return;
|
|
}
|
|
|
|
let mesh = null;
|
|
if (meshContent.type === 'cuboid') {
|
|
if (parameters.size_x === undefined || parameters.size_y === undefined || parameters.size_z === undefined) {
|
|
return;
|
|
}
|
|
mesh = GenerateCuboid (genParams, parameters.size_x, parameters.size_y, parameters.size_z);
|
|
} else if (meshContent.type === 'cylinder') {
|
|
if (parameters.radius === undefined || parameters.height === undefined) {
|
|
return;
|
|
}
|
|
let segments = ValueOrDefault (parameters.segments, 25);
|
|
let smooth = ValueOrDefault (parameters.smooth, true);
|
|
mesh = GenerateCylinder (genParams, parameters.radius, parameters.height, segments, smooth);
|
|
} else if (meshContent.type === 'cone') {
|
|
if (parameters.top_radius === undefined || parameters.bottom_radius === undefined || parameters.height === undefined) {
|
|
return;
|
|
}
|
|
let segments = ValueOrDefault (parameters.segments, 25);
|
|
let smooth = ValueOrDefault (parameters.smooth, true);
|
|
mesh = GenerateCone (genParams, parameters.top_radius, parameters.bottom_radius, parameters.height, segments, smooth);
|
|
} else if (meshContent.type === 'sphere') {
|
|
if (parameters.radius === undefined) {
|
|
return;
|
|
}
|
|
let segments = ValueOrDefault (parameters.segments, 20);
|
|
let smooth = ValueOrDefault (parameters.smooth, true);
|
|
mesh = GenerateSphere (genParams, parameters.radius, segments, smooth);
|
|
} else if (meshContent.type === 'platonic') {
|
|
if (parameters.solid_type === undefined) {
|
|
return;
|
|
}
|
|
let radius = ValueOrDefault (parameters.radius, 1.0);
|
|
mesh = GeneratePlatonicSolid (genParams, parameters.solid_type, radius);
|
|
}
|
|
if (mesh !== null) {
|
|
this.ImportProperties (mesh, meshContent);
|
|
this.model.AddMesh (mesh);
|
|
}
|
|
}
|
|
|
|
ImportNode (content, nodeContent, node)
|
|
{
|
|
if (nodeContent.name !== undefined) {
|
|
node.SetName (nodeContent.name);
|
|
}
|
|
if (nodeContent.transformation !== undefined) {
|
|
const nodeTransformation = this.GetTransformation (nodeContent.transformation);
|
|
node.SetTransformation (nodeTransformation);
|
|
}
|
|
if (nodeContent.children !== undefined) {
|
|
for (const childIndex of nodeContent.children) {
|
|
let childContent = content.nodes[childIndex];
|
|
let childNode = new Node ();
|
|
node.AddChildNode (childNode);
|
|
this.ImportNode (content, childContent, childNode);
|
|
}
|
|
}
|
|
if (nodeContent.mesh !== undefined) {
|
|
if (nodeContent.children === undefined || nodeContent.children.length === 0) {
|
|
node.SetType (NodeType.MeshNode);
|
|
}
|
|
node.AddMeshIndex (nodeContent.mesh);
|
|
}
|
|
}
|
|
|
|
ImportProperties (element, nodeContent)
|
|
{
|
|
if (nodeContent.properties !== undefined) {
|
|
const propertyGroup = new PropertyGroup ('Properties');
|
|
element.AddPropertyGroup (propertyGroup);
|
|
for (const nodeProperty of nodeContent.properties) {
|
|
const property = new Property (PropertyType.Text, nodeProperty.name, nodeProperty.value);
|
|
propertyGroup.AddProperty (property);
|
|
}
|
|
}
|
|
}
|
|
|
|
GetTransformation (contentTransformation)
|
|
{
|
|
let translation = new Coord3D (0.0, 0.0, 0.0);
|
|
let rotation = new Quaternion (0.0, 0.0, 0.0, 1.0);
|
|
let scale = new Coord3D (1.0, 1.0, 1.0);
|
|
if (contentTransformation.translation !== undefined) {
|
|
translation = ArrayToCoord3D (contentTransformation.translation);
|
|
}
|
|
if (contentTransformation.rotation !== undefined) {
|
|
rotation = ArrayToQuaternion (contentTransformation.rotation);
|
|
}
|
|
if (contentTransformation.scale !== undefined) {
|
|
scale = ArrayToCoord3D (contentTransformation.scale);
|
|
}
|
|
const matrix = new Matrix ().ComposeTRS (translation, rotation, scale);
|
|
return new Transformation (matrix);
|
|
}
|
|
}
|