/**
* CSS 3D engine
*
* @category css3d
* @package css3d.elementFactory
* @author Jan Fischer, bitWorking <info@bitworking.de>
* @copyright 2014 Jan Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
/**
*
* @namespace
*/
css3d.elementFactory = {
/**
*
* @param {DOMElement} container
* @param {css3d.scene} scene
* @param {Number} size
* @param {String|null} id
* @param {String|null} className
* @param {Boolean|null} backfaceCulling
* @param {Boolean|null} shading
* @returns {css3d.element} This is the parent element
*/
cube : function(container, scene, size, id, className, backfaceCulling, shading)
{
var translation = size/2;
var elementGroup = new css3d.element();
elementGroup.setTranslation(0, 0, -translation);
var backDiv = document.createElement('div');
backDiv.style.position = 'absolute';
backDiv.style.width = size+'px';
backDiv.style.height = size+'px';
container.appendChild(backDiv);
var frontDiv = document.createElement('div');
frontDiv.style.position = 'absolute';
frontDiv.style.width = size+'px';
frontDiv.style.height = size+'px';
container.appendChild(frontDiv);
var leftDiv = document.createElement('div');
leftDiv.style.position = 'absolute';
leftDiv.style.width = size+'px';
leftDiv.style.height = size+'px';
container.appendChild(leftDiv);
var rightDiv = document.createElement('div');
rightDiv.style.position = 'absolute';
rightDiv.style.width = size+'px';
rightDiv.style.height = size+'px';
container.appendChild(rightDiv);
var topDiv = document.createElement('div');
topDiv.style.position = 'absolute';
topDiv.style.width = size+'px';
topDiv.style.height = size+'px';
container.appendChild(topDiv);
var bottomDiv = document.createElement('div');
bottomDiv.style.position = 'absolute';
bottomDiv.style.width = size+'px';
bottomDiv.style.height = size+'px';
container.appendChild(bottomDiv);
if (id) {
backDiv.id = id+'-back';
frontDiv.id = id+'-front';
leftDiv.id = id+'-left';
rightDiv.id = id+'-right';
topDiv.id = id+'-top';
bottomDiv.id = id+'-bottom';
}
if (className) {
backDiv.className = className+' '+className+'-back';
frontDiv.className = className+' '+className+'-front';
leftDiv.className = className+' '+className+'-left';
rightDiv.className = className+' '+className+'-right';
topDiv.className = className+' '+className+'-top';
bottomDiv.className = className+' '+className+'-bottom';
}
backfaceCulling = (backfaceCulling == null) ? true : backfaceCulling;
shading = (shading == null) ? true : shading;
var back = new css3d.element(backDiv);
back.setBackfaceCulling(backfaceCulling);
back.shading = shading;
back.setTranslation(0, 0, -translation);
back.setRotation({x:0, y:1, z:0}, Math.PI);
back.inheritScaling = true;
var front = new css3d.element(frontDiv);
front.setBackfaceCulling(backfaceCulling);
front.shading = shading;
front.setTranslation(0, 0, translation);
front.inheritScaling = true;
var left = new css3d.element(leftDiv);
left.setBackfaceCulling(backfaceCulling);
left.shading = shading;
left.setRotation({x:0, y:1, z:0}, -Math.PI/2);
left.setTranslation(-translation, 0, 0);
left.inheritScaling = true;
var right = new css3d.element(rightDiv);
right.setBackfaceCulling(backfaceCulling);
right.shading = shading;
right.setRotation({x:0, y:1, z:0}, Math.PI/2);
right.setTranslation(translation, 0, 0);
right.inheritScaling = true;
var top = new css3d.element(topDiv);
top.setBackfaceCulling(backfaceCulling);
top.shading = shading;
top.setRotation({x:1, y:0, z:0}, Math.PI/2);
top.setTranslation(0, -translation, 0);
top.inheritScaling = true;
var bottom = new css3d.element(bottomDiv);
bottom.setBackfaceCulling(backfaceCulling);
bottom.shading = shading;
bottom.setRotation({x:1, y:0, z:0}, -Math.PI/2);
bottom.setTranslation(0, translation, 0);
bottom.inheritScaling = true;
back.setParent(elementGroup);
front.setParent(elementGroup);
left.setParent(elementGroup);
right.setParent(elementGroup);
top.setParent(elementGroup);
bottom.setParent(elementGroup);
scene.addElement(elementGroup);
scene.addElement(back);
scene.addElement(front);
scene.addElement(left);
scene.addElement(right);
scene.addElement(top);
scene.addElement(bottom);
return elementGroup;
},
/**
*
* @param {DOMElement} container
* @param {css3d.scene} scene
* @param {Number} width
* @param {Number} height
* @param {Number} depth
* @param {String|null} id
* @param {String|null} className
* @param {Boolean|null} backfaceCulling
* @param {Boolean|null} shading
* @param {Boolean|null} addTopAndBottom
* @returns {css3d.element} This is the parent element
*/
cuboid : function(container, scene, width, height, depth, id, className, backfaceCulling, shading, addTopAndBottom)
{
var translationX = width/2;
var translationY = height/2;
var translationZ = depth/2;
addTopAndBottom = (addTopAndBottom == null) ? true : addTopAndBottom;
var elementGroup = new css3d.element();
elementGroup.setTranslation(0, 0, -translationZ);
var backDiv = document.createElement('div');
backDiv.style.position = 'absolute';
backDiv.style.width = width+'px';
backDiv.style.height = height+'px';
container.appendChild(backDiv);
var frontDiv = document.createElement('div');
frontDiv.style.position = 'absolute';
frontDiv.style.width = width+'px';
frontDiv.style.height = height+'px';
container.appendChild(frontDiv);
var leftDiv = document.createElement('div');
leftDiv.style.position = 'absolute';
leftDiv.style.width = depth+'px';
leftDiv.style.height = height+'px';
container.appendChild(leftDiv);
var rightDiv = document.createElement('div');
rightDiv.style.position = 'absolute';
rightDiv.style.width = depth+'px';
rightDiv.style.height = height+'px';
container.appendChild(rightDiv);
if (addTopAndBottom) {
var topDiv = document.createElement('div');
topDiv.style.position = 'absolute';
topDiv.style.width = width+'px';
topDiv.style.height = depth+'px';
container.appendChild(topDiv);
var bottomDiv = document.createElement('div');
bottomDiv.style.position = 'absolute';
bottomDiv.style.width = width+'px';
bottomDiv.style.height = depth+'px';
container.appendChild(bottomDiv);
}
if (id) {
backDiv.id = id+'-back';
frontDiv.id = id+'-front';
leftDiv.id = id+'-left';
rightDiv.id = id+'-right';
if (addTopAndBottom) {
topDiv.id = id+'-top';
bottomDiv.id = id+'-bottom';
}
}
if (className) {
backDiv.className = className+' '+className+'-back';
frontDiv.className = className+' '+className+'-front';
leftDiv.className = className+' '+className+'-left';
rightDiv.className = className+' '+className+'-right';
if (addTopAndBottom) {
topDiv.className = className+' '+className+'-top';
bottomDiv.className = className+' '+className+'-bottom';
}
}
backfaceCulling = (backfaceCulling == null) ? true : backfaceCulling;
shading = (shading == null) ? true : shading;
var back = new css3d.element(backDiv);
back.setBackfaceCulling(backfaceCulling);
back.shading = shading;
back.setTranslation(0, 0, -translationZ);
back.setRotation({x:0, y:1, z:0}, Math.PI);
back.inheritScaling = true;
var front = new css3d.element(frontDiv);
front.setBackfaceCulling(backfaceCulling);
front.shading = shading;
front.setTranslation(0, 0, translationZ);
front.inheritScaling = true;
var left = new css3d.element(leftDiv);
left.setBackfaceCulling(backfaceCulling);
left.shading = shading;
left.setRotation({x:0, y:1, z:0}, -Math.PI/2);
left.setTranslation(-translationX, 0, 0);
left.inheritScaling = true;
var right = new css3d.element(rightDiv);
right.setBackfaceCulling(backfaceCulling);
right.shading = shading;
right.setRotation({x:0, y:1, z:0}, Math.PI/2);
right.setTranslation(translationX, 0, 0);
right.inheritScaling = true;
if (addTopAndBottom) {
var top = new css3d.element(topDiv);
top.setBackfaceCulling(backfaceCulling);
top.shading = shading;
top.setRotation({x:1, y:0, z:0}, Math.PI/2);
top.setTranslation(0, -translationY, 0);
top.inheritScaling = true;
var bottom = new css3d.element(bottomDiv);
bottom.setBackfaceCulling(backfaceCulling);
bottom.shading = shading;
bottom.setRotation({x:1, y:0, z:0}, -Math.PI/2);
bottom.setTranslation(0, translationY, 0);
bottom.inheritScaling = true;
}
back.setParent(elementGroup);
front.setParent(elementGroup);
left.setParent(elementGroup);
right.setParent(elementGroup);
if (addTopAndBottom) {
top.setParent(elementGroup);
bottom.setParent(elementGroup);
}
scene.addElement(elementGroup);
scene.addElement(back);
scene.addElement(front);
scene.addElement(left);
scene.addElement(right);
if (addTopAndBottom) {
scene.addElement(top);
scene.addElement(bottom);
}
return elementGroup;
},
/**
* Build cube from DOM Elements
*
* @param {css3d.scene} scene
* @param {Number} size
* @param {DOMElement} backE
* @param {DOMElement} frontE
* @param {DOMElement} leftE
* @param {DOMElement} rightE
* @param {DOMElement} topE
* @param {DOMElement} bottomE
* @param {Boolean|null} backfaceCulling
* @param {Boolean|null} shading
* @returns {css3d.element} This is the parent element
*/
cubeElements : function(scene, size, backE, frontE, leftE, rightE, topE, bottomE, backfaceCulling, shading)
{
var translation = size/2;
var elementGroup = new css3d.element();
elementGroup.setTranslation(0, 0, -translation);
backE.style.position = 'absolute';
frontE.style.position = 'absolute';
leftE.style.position = 'absolute';
rightE.style.position = 'absolute';
topE.style.position = 'absolute';
bottomE.style.position = 'absolute';
backfaceCulling = (backfaceCulling == null) ? true : backfaceCulling;
shading = (shading == null) ? true : shading;
var back = new css3d.element(backE);
back.setBackfaceCulling(backfaceCulling);
back.shading = shading;
back.setTranslation(0, 0, -translation);
back.setRotation({x:0, y:1, z:0}, Math.PI);
back.inheritScaling = true;
var front = new css3d.element(frontE);
front.setBackfaceCulling(backfaceCulling);
front.shading = shading;
front.setTranslation(0, 0, translation);
front.inheritScaling = true;
var left = new css3d.element(leftE);
left.setBackfaceCulling(backfaceCulling);
left.shading = shading;
left.setRotation({x:0, y:1, z:0}, -Math.PI/2);
left.setTranslation(-translation, 0, 0);
left.inheritScaling = true;
var right = new css3d.element(rightE);
right.setBackfaceCulling(backfaceCulling);
right.shading = shading;
right.setRotation({x:0, y:1, z:0}, Math.PI/2);
right.setTranslation(translation, 0, 0);
right.inheritScaling = true;
var top = new css3d.element(topE);
top.setBackfaceCulling(backfaceCulling);
top.shading = shading;
top.setRotation({x:1, y:0, z:0}, Math.PI/2);
top.setTranslation(0, -translation, 0);
top.inheritScaling = true;
var bottom = new css3d.element(bottomE);
bottom.setBackfaceCulling(backfaceCulling);
bottom.shading = shading;
bottom.setRotation({x:1, y:0, z:0}, -Math.PI/2);
bottom.setTranslation(0, translation, 0);
bottom.inheritScaling = true;
back.setParent(elementGroup);
front.setParent(elementGroup);
left.setParent(elementGroup);
right.setParent(elementGroup);
top.setParent(elementGroup);
bottom.setParent(elementGroup);
scene.addElement(elementGroup);
scene.addElement(back);
scene.addElement(front);
scene.addElement(left);
scene.addElement(right);
scene.addElement(top);
scene.addElement(bottom);
return elementGroup;
},
/* test with container element and native css transformation */
cube2 : function(container, css3dInstance, scene, size, id, className)
{
var translation = size/2;
var mainDiv = document.createElement('div');
mainDiv.style.position = 'absolute';
mainDiv.style[css3dInstance._styleTransformStyle] = 'preserve-3d';
container.appendChild(mainDiv);
var backDiv = document.createElement('div');
backDiv.style.position = 'absolute';
mainDiv.appendChild(backDiv);
var frontDiv = document.createElement('div');
frontDiv.style.position = 'absolute';
mainDiv.appendChild(frontDiv);
var leftDiv = document.createElement('div');
leftDiv.style.position = 'absolute';
mainDiv.appendChild(leftDiv);
var rightDiv = document.createElement('div');
rightDiv.style.position = 'absolute';
mainDiv.appendChild(rightDiv);
var topDiv = document.createElement('div');
topDiv.style.position = 'absolute';
mainDiv.appendChild(topDiv);
var bottomDiv = document.createElement('div');
bottomDiv.style.position = 'absolute';
mainDiv.appendChild(bottomDiv);
if (id) {
mainDiv.id = id+'-main';
backDiv.id = id+'-back';
frontDiv.id = id+'-front';
leftDiv.id = id+'-left';
rightDiv.id = id+'-right';
topDiv.id = id+'-top';
bottomDiv.id = id+'-bottom';
}
if (className) {
mainDiv.className = className+' '+className+'-main';
backDiv.className = className+' '+className+'-back';
frontDiv.className = className+' '+className+'-front';
leftDiv.className = className+' '+className+'-left';
rightDiv.className = className+' '+className+'-right';
topDiv.className = className+' '+className+'-top';
bottomDiv.className = className+' '+className+'-bottom';
}
var main = new css3d.element(mainDiv);
main.setTranslation(0, 0, -translation);
main.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var back = new css3d.element(backDiv);
back.setBackfaceCulling(true);
back.setTranslation(0, 0, -translation);
back.setRotation({x:0, y:1, z:0}, Math.PI);
back.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var front = new css3d.element(frontDiv);
front.setBackfaceCulling(true);
front.setTranslation(0, 0, translation);
front.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var left = new css3d.element(leftDiv);
left.setBackfaceCulling(true);
left.setRotation({x:0, y:1, z:0}, -Math.PI/2);
left.setTranslation(-translation, 0, 0);
left.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var right = new css3d.element(rightDiv);
right.setBackfaceCulling(true);
right.setRotation({x:0, y:1, z:0}, Math.PI/2);
right.setTranslation(translation, 0, 0);
right.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var top = new css3d.element(topDiv);
top.setBackfaceCulling(true);
top.setRotation({x:1, y:0, z:0}, Math.PI/2);
top.setTranslation(0, -translation, 0);
top.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
var bottom = new css3d.element(bottomDiv);
bottom.setBackfaceCulling(true);
bottom.setRotation({x:1, y:0, z:0}, -Math.PI/2);
bottom.setTranslation(0, translation, 0);
bottom.setMatrix(css3dInstance._styleTransform, css3dInstance._styleBackfaceVisibility);
scene.addElement(main);
return main;
},
/**
*
* @param {DOMElement} container
* @param {css3d.scene} scene
* @param {Number} size
* @param {Integer} tiles
* @param {String|null} id
* @param {String|null} className
* @param {Boolean|null} backfaceCulling
* @param {Boolean|null} shading
* @returns {css3d.element} This is the parent element
*/
plane : function(container, scene, size, tiles, id, className, backfaceCulling, shading)
{
var tileSize = size/tiles;
var sizeHalf = (size/2);
var elementGroup = new css3d.element();
scene.addElement(elementGroup);
backfaceCulling = (backfaceCulling == null) ? true : backfaceCulling;
shading = (shading == null) ? true : shading;
var tmp;
var tmp2;
// rows
for (var i=0;i<tiles;i++) {
// tiles
for (var j=0;j<tiles;j++) {
tmp = document.createElement('div');
tmp.style.position = 'absolute';
tmp.style.width = tileSize+'px';
tmp.style.height = tileSize+'px';
container.appendChild(tmp);
if (id) {
tmp.id = id+'-'+i+'-'+j;
}
if (className) {
tmp.className = className+' '+className+'-'+i+'-'+j;
}
tmp2 = new css3d.element(tmp);
tmp2.setBackfaceCulling(backfaceCulling);
tmp2.shading = shading;
tmp2.setTranslation(-sizeHalf + (j * tileSize), -sizeHalf + (i * tileSize), 0);
tmp2.inheritScaling = true;
tmp2.setParent(elementGroup);
scene.addElement(tmp2);
}
}
return elementGroup;
},
/**
*
* @param {DOMElement} container
* @param {css3d.scene} scene
* @param {Number} size
* @param {String|null} id
* @param {String|null} className
* @returns {css3d.element} This is the parent element
*/
skybox : function(container, scene, size, id, className)
{
var translation = (size-2)/2;
var elementGroup = new css3d.element();
var backDiv = document.createElement('div');
backDiv.style.position = 'absolute';
backDiv.style.width = size+'px';
backDiv.style.height = size+'px';
container.appendChild(backDiv);
var frontDiv = document.createElement('div');
frontDiv.style.position = 'absolute';
frontDiv.style.width = size+'px';
frontDiv.style.height = size+'px';
container.appendChild(frontDiv);
var leftDiv = document.createElement('div');
leftDiv.style.position = 'absolute';
leftDiv.style.width = size+'px';
leftDiv.style.height = size+'px';
container.appendChild(leftDiv);
var rightDiv = document.createElement('div');
rightDiv.style.position = 'absolute';
rightDiv.style.width = size+'px';
rightDiv.style.height = size+'px';
container.appendChild(rightDiv);
var topDiv = document.createElement('div');
topDiv.style.position = 'absolute';
topDiv.style.width = size+'px';
topDiv.style.height = size+'px';
container.appendChild(topDiv);
var bottomDiv = document.createElement('div');
bottomDiv.style.position = 'absolute';
bottomDiv.style.width = size+'px';
bottomDiv.style.height = size+'px';
container.appendChild(bottomDiv);
if (id) {
backDiv.id = id+'-back';
frontDiv.id = id+'-front';
leftDiv.id = id+'-left';
rightDiv.id = id+'-right';
topDiv.id = id+'-top';
bottomDiv.id = id+'-bottom';
}
if (className) {
backDiv.className = className+' '+className+'-back';
frontDiv.className = className+' '+className+'-front';
leftDiv.className = className+' '+className+'-left';
rightDiv.className = className+' '+className+'-right';
topDiv.className = className+' '+className+'-top';
bottomDiv.className = className+' '+className+'-bottom';
}
var backfaceCulling = true;
var shading = false;
var back = new css3d.element(backDiv);
back.setBackfaceCulling(backfaceCulling);
back.shading = shading;
back.setTranslation(0, 0, -translation);
back.inheritScaling = true;
var front = new css3d.element(frontDiv);
front.setBackfaceCulling(backfaceCulling);
front.shading = shading;
front.setTranslation(0, 0, translation);
front.setRotation({x:0, y:1, z:0}, Math.PI);
front.inheritScaling = true;
var left = new css3d.element(leftDiv);
left.setBackfaceCulling(backfaceCulling);
left.shading = shading;
left.setRotation({x:0, y:1, z:0}, Math.PI/2);
left.setTranslation(-translation, 0, 0);
left.inheritScaling = true;
var right = new css3d.element(rightDiv);
right.setBackfaceCulling(backfaceCulling);
right.shading = shading;
right.setRotation({x:0, y:1, z:0}, -Math.PI/2);
right.setTranslation(translation, 0, 0);
right.inheritScaling = true;
var top = new css3d.element(topDiv);
top.setBackfaceCulling(backfaceCulling);
top.shading = shading;
top.setRotation({x:1, y:0, z:0}, -Math.PI/2);
top.setTranslation(0, -translation, 0);
top.inheritScaling = true;
var bottom = new css3d.element(bottomDiv);
bottom.setBackfaceCulling(backfaceCulling);
bottom.shading = shading;
bottom.setRotation({x:1, y:0, z:0}, Math.PI/2);
bottom.setTranslation(0, translation, 0);
bottom.inheritScaling = true;
back.setParent(elementGroup);
front.setParent(elementGroup);
left.setParent(elementGroup);
right.setParent(elementGroup);
top.setParent(elementGroup);
bottom.setParent(elementGroup);
scene.addElement(elementGroup);
scene.addElement(back);
scene.addElement(front);
scene.addElement(left);
scene.addElement(right);
scene.addElement(top);
scene.addElement(bottom);
return elementGroup;
},
/**
* Import an obj file
*
* @param {DOMElement} container
* @param {css3d.scene} scene
* @param {String} objFile Path to obj file
* @param {String|null} className
* @param {Boolean|null} backfaceCulling
* @param {Boolean|null} shading
* @param {Boolean|null} clockwise The face winding direction
* @param {String} textureFile Path to texture file
* @param {Integer} textureSize Texture size (The texture has to be a square)
* @returns {css3d.element} This is the parent element
*/
fromObj : function(container, scene, objFile, className, backfaceCulling, shading, clockwise, textureFile, textureSize)
{
className = className || 'model';
backfaceCulling = (backfaceCulling == null) ? true : backfaceCulling;
shading = (shading == null) ? true : shading;
clockwise = (clockwise == null) ? false : clockwise;
textureFile = (textureFile == null) ? '' : textureFile;
textureSize = (textureSize == null) ? 1024 : textureSize;
var objContent = css3d.ajax.getS(objFile);
var vertices = [];
var faces = [];
var colors = [];
colors[0] = [204, 204, 204];
var textureCoordinates = [];
var faceMatches = [];
var findColors = /c ([0-9]*) ([0-9]*) ([0-9]*)/gim;
var findVertices = /v ([0-9\-.]*) ([0-9\-.]*) ([0-9\-.]*)/gim;
//var findFaces1 = /f ([0-9\-.]*).*? ([0-9\-.]*).*? ([0-9\-.]*).*? ([0-9\-.]*)(.*)$/gim;
var findFaces1 = /f ([0-9\-.]*) ([0-9\-.]*) ([0-9\-.]*) ([0-9\-.]*)(.*)$/gim;
var findFaces2 = /f ([0-9\-.]*).*?\/([0-9\-.]*).*? ([0-9\-.]*).*?\/([0-9\-.]*).*? ([0-9\-.]*).*?\/([0-9\-.]*).*? ([0-9\-.]*).*?\/([0-9\-.]*)(.*)$/gim;
var findFaceColor = /[0-9\/.]* ([0-9])$/;
var findTextureCoordinates = /vt ([0-9\-.]*) ([0-9\-.]*) ([0-9\-.]*)/gim;
var matches = false;
/*
while (matches = findColors.exec(objContent)) {
colors.push([parseInt(matches[1]), parseInt(matches[2]), parseInt(matches[3])]);
}
*/
while (matches = findVertices.exec(objContent)) {
vertices.push([parseFloat(matches[1])*-1, parseFloat(matches[2]), parseFloat(matches[3])]);
}
while (matches = findTextureCoordinates.exec(objContent)) {
textureCoordinates.push([parseFloat(matches[1]), parseFloat(matches[2]), parseFloat(matches[3])]);
}
var elementGroup = new css3d.element();
var count = 0;
while (matches = findFaces1.exec(objContent)) {
faceMatches.push(matches);
}
while (matches = findFaces2.exec(objContent)) {
faceMatches.push(matches);
}
var i=0
while (matches = faceMatches[i++]) {
if (matches.length < 5) {
continue;
}
if (matches.length >= 9) {
var f0 = Math.abs(parseInt(matches[1]))-1;
var f1 = Math.abs(parseInt(matches[3]))-1;
var f2 = Math.abs(parseInt(matches[5]))-1;
var f3 = Math.abs(parseInt(matches[7]))-1;
var ft0 = Math.abs(parseInt(matches[2]))-1;
var ft1 = Math.abs(parseInt(matches[4]))-1;
var ft2 = Math.abs(parseInt(matches[6]))-1;
var ft3 = Math.abs(parseInt(matches[8]))-1;
var vt0 = new css3d.vector3(textureCoordinates[ft0][0], textureCoordinates[ft0][1], textureCoordinates[ft0][2]);
var vt1 = new css3d.vector3(textureCoordinates[ft1][0], textureCoordinates[ft1][1], textureCoordinates[ft1][2]);
var vt2 = new css3d.vector3(textureCoordinates[ft2][0], textureCoordinates[ft2][1], textureCoordinates[ft2][2]);
var vt3 = new css3d.vector3(textureCoordinates[ft3][0], textureCoordinates[ft3][1], textureCoordinates[ft3][2]);
}
else if (matches.length >= 5) {
var f0 = Math.abs(parseInt(matches[1]))-1;
var f1 = Math.abs(parseInt(matches[2]))-1;
var f2 = Math.abs(parseInt(matches[3]))-1;
var f3 = Math.abs(parseInt(matches[4]))-1;
}
var v0 = new css3d.vector3(vertices[f0][0], vertices[f0][1], vertices[f0][2]);
var v1 = new css3d.vector3(vertices[f1][0], vertices[f1][1], vertices[f1][2]);
var v2 = new css3d.vector3(vertices[f2][0], vertices[f2][1], vertices[f2][2]);
var v3 = new css3d.vector3(vertices[f3][0], vertices[f3][1], vertices[f3][2]);
// get normal
var normal = css3d.vector3.prototype.cross(
css3d.vector3.prototype.sub2(v1, v0),
css3d.vector3.prototype.sub2(v2, v0)
).normalize();
if (!clockwise) {
normal.x = -normal.x;
normal.y = -normal.y;
normal.z = -normal.z;
}
// build rotation matrix
var xAxis = css3d.vector3.prototype.cross(normal, css3d.vector3.prototype.sub2(v1, v0).normalize()).normalize();
var yAxis = css3d.vector3.prototype.cross(normal, xAxis);
var zAxis = normal;
var rotationMatrix = [
xAxis.x, yAxis.x, zAxis.x, 0,
xAxis.y, yAxis.y, zAxis.y, 0,
xAxis.z, yAxis.z, zAxis.z, 0,
0, 0, 0, 1
];
// get dimension
var width = Math.sqrt(Math.pow(v2.x - v1.x, 2) + Math.pow(v2.y - v1.y, 2) + Math.pow(v2.z - v1.z, 2)).toFixed(4);
var height = Math.sqrt(Math.pow(v1.x - v0.x, 2) + Math.pow(v1.y - v0.y, 2) + Math.pow(v1.z - v0.z, 2)).toFixed(4);
// get position
var x = ((v0.x + v1.x + v2.x + v3.x) / 4.0);
var y = ((v0.y + v1.y + v2.y + v3.y) / 4.0);
var z = ((v0.z + v1.z + v2.z + v3.z) / 4.0);
// build element
var div = document.createElement('div');
div.className = className+' '+className+'-'+count;
div.style.position = 'absolute';
div.style.width = width+'px';
div.style.height = height+'px';
div.style.backgroundColor = '#ccc';
// texture mapping
if (matches.length >= 9) {
var tx0 = vt0.x * textureSize;
var ty0 = textureSize - (vt0.y * textureSize);
var tx1 = vt1.x * textureSize;
var ty1 = textureSize - (vt1.y * textureSize);
var tx2 = vt2.x * textureSize;
var ty2 = textureSize - (vt2.y * textureSize);
var tx3 = vt3.x * textureSize;
var ty3 = textureSize - (vt3.y * textureSize);
var vWidth = tx3 - tx1;
if (vWidth < 0) {
vWidth = tx1 - tx3;
tx1 = tx2;
}
var vHeight = ty3 - ty1;
if (vHeight < 0) {
vHeight = ty1 - ty3;
ty1 = ty2;
}
var scaleX = width/vWidth;
var scaleY = height/vHeight;
// TODO:
// there is a problem with texture rotation
// some elements are 90 or 180 degrees rotated
div.style.backgroundPosition = (-tx1*scaleX).toFixed(4)+'px '+(-ty1*scaleY).toFixed(4)+'px';
div.style.backgroundImage = 'url("'+textureFile+'")';
div.style.backgroundSize = (textureSize*scaleX).toFixed(4)+'px '+(textureSize*scaleY).toFixed(4)+'px';
}
container.appendChild(div);
var element = new css3d.element(div);
element.setBackfaceCulling(backfaceCulling);
element.shading = shading;
element.setTranslation(x, y, z);
element.setRotationMatrix(rotationMatrix);
element.inheritScaling = true;
element.setParent(elementGroup);
scene.addElement(element);
count++;
}
console.log('obj file loaded. ' + count + ' faces');
elementGroup.setScale(-1, -1, 1);
scene.addElement(elementGroup);
return elementGroup;
}
};