mdx-m3-viewer
Version:
A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.
124 lines (92 loc) • 3.03 kB
text/typescript
import MdlxModel from '../../../parsers/mdlx/model';
import MdlxTexture from '../../../parsers/mdlx/texture';
import MdlxMaterial from '../../../parsers/mdlx/material';
import MdlxLayer from '../../../parsers/mdlx/layer';
import MdlxGeoset from '../../../parsers/mdlx/geoset';
import MdlxGeosetAnimation from '../../../parsers/mdlx/geosetanimation';
import MdlxBone from '../../../parsers/mdlx/bone';
import ModelViewer from '../../../viewer/viewer';
import { PathSolver } from '../../../viewer/handlerresource';
import Texture from '../../../viewer/texture';
interface Primitive {
vertices: Float32Array;
uvs: Float32Array;
faces: Uint16Array;
edges: Uint16Array;
boundingRadius: number;
}
interface Material {
lines?: boolean;
color?: Float32Array;
texture?: Texture | Promise<Texture>;
twoSided?: boolean;
}
export default function createPrimitive(viewer: ModelViewer, primitive: Primitive, material: Material) {
let lines: boolean | undefined;
let color: Float32Array | undefined;
let texture: Texture | Promise<Texture> | undefined;
let pathSolver: PathSolver | undefined;
let layerFlags = 0;
if (material) {
lines = material.lines;
color = material.color;
texture = material.texture;
if (material.twoSided) {
layerFlags |= 0x10;
}
}
let model = new MdlxModel();
// Extent
let extent = model.extent;
let r = primitive.boundingRadius;
extent.min.fill(-r);
extent.max.fill(r);
extent.boundsRadius = r;
// Texture
let tex = new MdlxTexture();
tex.path = 'PLACEHOLDER';
model.textures[0] = tex;
pathSolver = (src) => {
if (src === model) {
return model;
}
return texture;
}
// Material
let mat = new MdlxMaterial();
let layer = new MdlxLayer();
layer.textureId = 0;
layer.flags = layerFlags;
mat.layers[0] = layer;
model.materials[0] = mat;
// Geoset
let geoset = new MdlxGeoset();
geoset.vertices = primitive.vertices;
geoset.uvSets[0] = primitive.uvs;
geoset.matrixGroups = new Uint32Array([1]);
geoset.matrixIndices = new Uint32Array([0]);
geoset.vertexGroups = new Uint8Array(primitive.vertices.length / 3);
let faceTypeGroup = 4;
let indices = primitive.faces;
if (lines) {
faceTypeGroup = 1;
indices = primitive.edges;
}
geoset.faceTypeGroups = new Uint32Array([faceTypeGroup]);
geoset.faceGroups = new Uint32Array([indices.length]);
geoset.faces = indices;
model.geosets[0] = geoset;
// Color via a geoset animation.
if (color) {
let geosetAnimation = new MdlxGeosetAnimation();
geosetAnimation.geosetId = 0;
geosetAnimation.color = color;
model.geosetAnimations[0] = geosetAnimation;
}
// Bone - otherwise can't transform the instance.
let bone = new MdlxBone();
bone.objectId = 0;
model.bones[0] = bone;
// Load and return the promise.
return viewer.load(model, pathSolver);
}