mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 04:56:01 +10:00
Updated Blender exporter to be able to export scenes.
Work-in-progress. So close yet so far. Test scene almost works, just two things are not rotated properly (which means maybe everything will need to be reworked :(
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* File generated with Blender 2.56 Exporter
|
||||
* https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/
|
||||
*
|
||||
* vertices: 8
|
||||
* faces: 6
|
||||
* normals: 0
|
||||
* uvs: 0
|
||||
* colors: 0
|
||||
* materials: 1
|
||||
*
|
||||
*/
|
||||
|
||||
var model = {
|
||||
|
||||
'version' : 2,
|
||||
|
||||
'materials': [ {
|
||||
"DbgColor" : 0xeeeeee,
|
||||
"DbgIndex" : 0,
|
||||
"DbgName" : "Material",
|
||||
"colorAmbient" : [0.0, 0.0, 0.0],
|
||||
"colorDiffuse" : [0.6400000190734865, 0.10179081114814892, 0.126246120426746],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"shading" : "Phong",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"vertexColors" : false
|
||||
}],
|
||||
|
||||
'vertices': [1.000000,-1.000000,-1.000000,1.000000,-1.000000,1.000000,-1.000000,-1.000000,1.000000,-1.000000,-1.000000,-1.000000,1.000000,1.000000,-1.000000,0.999999,1.000000,1.000001,-1.000000,1.000000,1.000000,-1.000000,1.000000,-1.000000],
|
||||
|
||||
'morphTargets': [],
|
||||
|
||||
'normals': [],
|
||||
|
||||
'colors': [],
|
||||
|
||||
'uvs': [[]],
|
||||
|
||||
'faces': [3,0,1,2,3,0,3,4,7,6,5,0,3,0,4,5,1,0,3,1,5,6,2,0,3,2,6,7,3,0,3,4,0,3,7,0],
|
||||
|
||||
'end': (new Date).getTime()
|
||||
|
||||
}
|
||||
|
||||
postMessage( model );
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* File generated with Blender 2.56 Exporter
|
||||
* https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/
|
||||
*
|
||||
* vertices: 4
|
||||
* faces: 1
|
||||
* normals: 0
|
||||
* uvs: 0
|
||||
* colors: 0
|
||||
* materials: 1
|
||||
*
|
||||
*/
|
||||
|
||||
var model = {
|
||||
|
||||
'version' : 2,
|
||||
|
||||
'materials': [ {
|
||||
"DbgColor" : 0xeeeeee,
|
||||
"DbgIndex" : 0,
|
||||
"DbgName" : "Material.001",
|
||||
"colorAmbient" : [0.0, 0.0, 0.0],
|
||||
"colorDiffuse" : [0.14462547517754842, 0.6400000190734865, 0.24541190036254967],
|
||||
"colorSpecular" : [0.5, 0.5, 0.5],
|
||||
"shading" : "Phong",
|
||||
"specularCoef" : 50,
|
||||
"transparency" : 1.0,
|
||||
"vertexColors" : false
|
||||
}],
|
||||
|
||||
'vertices': [1.000000,-0.000000,-1.000000,1.000000,0.000000,1.000000,-1.000000,0.000000,1.000000,-1.000000,-0.000000,-1.000000],
|
||||
|
||||
'morphTargets': [],
|
||||
|
||||
'normals': [],
|
||||
|
||||
'colors': [],
|
||||
|
||||
'uvs': [[]],
|
||||
|
||||
'faces': [3,0,3,2,1,0],
|
||||
|
||||
'end': (new Date).getTime()
|
||||
|
||||
}
|
||||
|
||||
postMessage( model );
|
||||
Binary file not shown.
@@ -0,0 +1,359 @@
|
||||
// Converted from: scene.blend
|
||||
// File generated with Blender 2.56 Exporter
|
||||
// https://github.com/alteredq/three.js/tree/master/utils/exporters/blender/
|
||||
|
||||
|
||||
var scene = {
|
||||
|
||||
"type" : "scene",
|
||||
"urlBaseType" : "relativeToScene",
|
||||
|
||||
|
||||
"objects" :
|
||||
{
|
||||
"Cube.006" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ 10.623673, 3.370784, -0.321692 ],
|
||||
"rotation" : [ 0.005265, -0.056306, 4.717181 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 8.310000, 4.930000, 0.120000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.018" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 1.702659, 0.680278, 5.860421 ],
|
||||
"rotation" : [ 1.413516, 0.081378, -3.204182 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.017" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 0.081295, 0.639505, 5.808783 ],
|
||||
"rotation" : [ 1.413516, 0.081378, -3.204182 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.016" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -1.569030, 0.619385, 5.747240 ],
|
||||
"rotation" : [ 1.413516, 0.081378, -3.204182 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.015" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -3.129120, 0.552267, 5.709269 ],
|
||||
"rotation" : [ 1.413516, 0.081378, -3.204182 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.014" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -6.386331, 0.382167, 3.004400 ],
|
||||
"rotation" : [ 1.646237, -0.058425, -1.670593 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.013" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -6.499331, 0.471640, 1.593073 ],
|
||||
"rotation" : [ 1.646237, -0.058425, -1.670593 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.012" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -6.629794, 0.533840, 0.234131 ],
|
||||
"rotation" : [ 1.646237, -0.058425, -1.670593 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.011" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -6.713673, 0.629835, -1.008146 ],
|
||||
"rotation" : [ 1.646237, -0.058425, -1.670593 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 0.435837, 0.435837, 0.435837 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.010" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -2.010442, 1.387332, 24.343616 ],
|
||||
"rotation" : [ 1.520470, 0.191726, -3.004622 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 9.160007, 9.160007, 9.160008 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.009" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -4.292194, 1.826282, -7.975398 ],
|
||||
"rotation" : [ 1.594819, 0.080713, -0.213986 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.008" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 2.151757, 1.891882, -8.065320 ],
|
||||
"rotation" : [ 1.594819, 0.080713, -0.213986 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.007" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -0.712512, 2.115002, -8.097841 ],
|
||||
"rotation" : [ 1.594819, 0.080713, -0.213986 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube.005" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ -1.000975, 1.319482, -8.755547 ],
|
||||
"rotation" : [ 0.000000, 0.000000, -0.000000 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 6.130000, 1.690000, 0.070000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube.004" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ 2.484517, 2.724846, 7.486932 ],
|
||||
"rotation" : [ 0.220417, -0.075224, 0.181029 ],
|
||||
"quaternion": [ 0.988791, 0.112836, 0.027288, -0.093898 ],
|
||||
"scale" : [ 0.350000, 3.310000, 0.890000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.006" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 7.724935, 1.694883, -7.123103 ],
|
||||
"rotation" : [ 1.835590, 0.083161, -2.048913 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.005" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -6.334642, 0.566791, -6.636147 ],
|
||||
"rotation" : [ 1.327136, -0.032561, -4.135900 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.004" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -5.384042, 0.444915, 6.194087 ],
|
||||
"rotation" : [ 0.991213, 0.181430, -5.246078 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.003" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 3.147747, 1.014840, 4.230884 ],
|
||||
"rotation" : [ 1.719311, -0.307044, -3.355401 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.002" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -2.668043, 3.008879, 2.153389 ],
|
||||
"rotation" : [ 1.881970, 0.457870, 4.066133 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube.003" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ -3.031251, 0.702044, 1.943665 ],
|
||||
"rotation" : [ -1.300741, -1.330343, 3.282723 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 1.781142, 0.231142, 0.361142 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey.001" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ 1.245307, 0.620196, -0.137285 ],
|
||||
"rotation" : [ 2.339869, -0.286025, -1.394760 ],
|
||||
"quaternion": [ -0.587711, 0.550951, 0.566613, 0.173203 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Monkey" : {
|
||||
"geometry" : "geo_Monkey",
|
||||
"materials" : [ "Material.002" ],
|
||||
"position" : [ -0.282500, 1.813606, -4.272932 ],
|
||||
"rotation" : [ 0.646062, -0.219349, -0.010569 ],
|
||||
"quaternion": [ 0.942751, 0.314982, 0.105460, -0.029764 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube.002" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ 0.042212, 5.536832, -0.199037 ],
|
||||
"rotation" : [ 0.000000, 0.000000, -0.000000 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube.001" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ -0.395497, 1.009696, -3.944532 ],
|
||||
"rotation" : [ 0.000000, 0.000000, -0.000000 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Plane" : {
|
||||
"geometry" : "geo_Plane",
|
||||
"materials" : [ "Material.001" ],
|
||||
"position" : [ 0.000000, 0.000000, 0.118260 ],
|
||||
"rotation" : [ 0.000000, 0.000000, -0.000000 ],
|
||||
"quaternion": [ 1.000000, 0.000000, 0.000000, 0.000000 ],
|
||||
"scale" : [ 7.922787, 7.922787, 7.922787 ],
|
||||
"visible" : true
|
||||
},
|
||||
|
||||
"Cube" : {
|
||||
"geometry" : "geo_Cube",
|
||||
"materials" : [ "Material" ],
|
||||
"position" : [ 3.651978, 1.071144, 0.000000 ],
|
||||
"rotation" : [ 0.220417, -0.075224, 0.181029 ],
|
||||
"quaternion": [ 0.988791, 0.112836, 0.027288, -0.093898 ],
|
||||
"scale" : [ 1.000000, 1.000000, 1.000000 ],
|
||||
"visible" : true
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"geometries" :
|
||||
{
|
||||
"geo_Cube" : {
|
||||
"type" : "ascii_mesh",
|
||||
"url" : "scene.Cube.js"
|
||||
},
|
||||
|
||||
"geo_Monkey" : {
|
||||
"type" : "ascii_mesh",
|
||||
"url" : "scene.Monkey.js"
|
||||
},
|
||||
|
||||
"geo_Plane" : {
|
||||
"type" : "ascii_mesh",
|
||||
"url" : "scene.Plane.js"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"materials" :
|
||||
{
|
||||
"Material" : {
|
||||
"type": "MeshPhongMaterial",
|
||||
"parameters": { color: 0xa31920, opacity: 1.00, ambient: 0x000000, specular: 0x7f7f7f, shininess: 50.0 }
|
||||
},
|
||||
|
||||
"Material.001" : {
|
||||
"type": "MeshPhongMaterial",
|
||||
"parameters": { color: 0x24a33e, opacity: 1.00, ambient: 0x000000, specular: 0x7f7f7f, shininess: 50.0 }
|
||||
},
|
||||
|
||||
"Material.002" : {
|
||||
"type": "MeshPhongMaterial",
|
||||
"parameters": { color: 0xa37024, opacity: 1.00, ambient: 0x000000, specular: 0x7f7f7f, shininess: 50.0 }
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"cameras" :
|
||||
{
|
||||
"default_camera" : {
|
||||
"type" : "perspective",
|
||||
"fov" : 60.000000,
|
||||
"aspect": 1.333000,
|
||||
"near" : 1.000000,
|
||||
"far" : 10000.000000,
|
||||
"position": [ 0.000000, 0.000000, 10.000000 ],
|
||||
"target" : [ 0.000000, 0.000000, 0.000000 ]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"lights" :
|
||||
{
|
||||
"default_light": {
|
||||
"type" : "directional",
|
||||
"direction" : [ 0.000000, 1.000000, 1.000000 ],
|
||||
"color" : 0xffffff,
|
||||
"intensity" : 0.80
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"defaults" :
|
||||
{
|
||||
"bgcolor" : [ 0.000000, 0.000000, 0.000000 ],
|
||||
"bgalpha" : 1.000000,
|
||||
"camera" : "default_camera"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
postMessage( scene );
|
||||
|
||||
@@ -0,0 +1,561 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>three.js webgl - io - scene loader [blender]</title>
|
||||
<meta charset="utf-8">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background:#000;
|
||||
color:#fff;
|
||||
padding:0;
|
||||
margin:0;
|
||||
overflow:hidden;
|
||||
font-family:georgia;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#info {
|
||||
position: absolute;
|
||||
top: 0px; width: 100%;
|
||||
padding: 5px;
|
||||
font-family: Monospace;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
z-index:100;
|
||||
}
|
||||
|
||||
#progress {
|
||||
color:red;
|
||||
top:7em;
|
||||
width: 100%;
|
||||
font-size:3em;
|
||||
font-variant:small-caps;
|
||||
font-weight:bold;
|
||||
position:absolute;
|
||||
z-index:100;
|
||||
text-align: center;
|
||||
text-shadow: #000 0px 0px 10px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
#start {
|
||||
color:#fff;
|
||||
text-shadow: #000 0px 0px 2px;
|
||||
padding:0.1em 0.3em;
|
||||
width:3em;
|
||||
text-align: center;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
-moz-box-shadow: 0px 0px 5px #000;
|
||||
-webkit-box-shadow: 0px 0px 5px #000;
|
||||
box-shadow: 0px 0px 5px #000;
|
||||
}
|
||||
|
||||
#progressbar {
|
||||
text-align: center;
|
||||
background: white;
|
||||
width: 250px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background:#d00;
|
||||
width:50px;
|
||||
height:10px;
|
||||
}
|
||||
|
||||
.enabled {
|
||||
color: lime!important;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.enabled:hover {
|
||||
text-shadow: #0f0 0px 0px 5px !important;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
background:gray;
|
||||
cursor:default;
|
||||
}
|
||||
|
||||
a { color:red }
|
||||
canvas { pointer-events:none; z-index:10; }
|
||||
#log { position:absolute; top:0; display:block; text-align:left; z-index:1000; pointer-events:none; }
|
||||
|
||||
#scene_explorer {
|
||||
background:transparent;
|
||||
color:#fff;
|
||||
width:200px;
|
||||
position:absolute;
|
||||
text-align:left;
|
||||
top:0px;
|
||||
z-index:200;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
#section_exp {
|
||||
background:rgba(0,0,50,0.5);
|
||||
padding:0.5em 0;
|
||||
display:none;
|
||||
}
|
||||
|
||||
#scene_explorer h3 {
|
||||
font-size:1em;
|
||||
padding:0;
|
||||
margin:0;
|
||||
color:orange;
|
||||
}
|
||||
|
||||
#scene_explorer a {
|
||||
color:#555;
|
||||
font-weight:bold;
|
||||
text-decoration:none;
|
||||
font-size:1.2em;
|
||||
font-family:Monospace;
|
||||
}
|
||||
#scene_explorer a:hover {
|
||||
background:#555;
|
||||
color:rgba(0,0,50,1);
|
||||
}
|
||||
|
||||
.part {
|
||||
display:none;
|
||||
padding:0 0 0.5em 2em;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="info">
|
||||
<a href="http://github.com/mrdoob/three.js">three.js</a> - scene loader test [blender]
|
||||
</div>
|
||||
|
||||
<div id="scene_explorer">
|
||||
<a id="plus_exp" href="#">[+]</a>
|
||||
<div id="section_exp"></div>
|
||||
</div>
|
||||
|
||||
<div id="progress">
|
||||
<span id="message">Loading ...</span>
|
||||
|
||||
<center>
|
||||
<div id="progressbar" class="shadow"><div id="bar" class="shadow"></div></div>
|
||||
<div id="start" class="disabled">Start</div>
|
||||
</center>
|
||||
</div>
|
||||
|
||||
<pre id="log"></pre>
|
||||
<!--
|
||||
<script type="text/javascript" src="../build/Three.js"></script>
|
||||
-->
|
||||
|
||||
<script type="text/javascript" src="../src/Three.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Color.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Vector2.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Vector3.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Vector4.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Ray.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Rectangle.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Matrix3.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Matrix4.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Object3D.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Quaternion.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Vertex.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Face3.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Face4.js"></script>
|
||||
<script type="text/javascript" src="../src/core/UV.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Geometry.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Spline.js"></script>
|
||||
<script type="text/javascript" src="../src/animation/AnimationHandler.js"></script>
|
||||
<script type="text/javascript" src="../src/animation/Animation.js"></script>
|
||||
<script type="text/javascript" src="../src/cameras/Camera.js"></script>
|
||||
<script type="text/javascript" src="../src/lights/Light.js"></script>
|
||||
<script type="text/javascript" src="../src/lights/AmbientLight.js"></script>
|
||||
<script type="text/javascript" src="../src/lights/DirectionalLight.js"></script>
|
||||
<script type="text/javascript" src="../src/lights/PointLight.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/Material.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/Mappings.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/LineBasicMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshBasicMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshLambertMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshPhongMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshDepthMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshNormalMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshFaceMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/MeshShaderMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/ParticleBasicMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/ParticleCanvasMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/ParticleDOMMaterial.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/Texture.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/RenderTarget.js"></script>
|
||||
<script type="text/javascript" src="../src/materials/Uniforms.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Particle.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/ParticleSystem.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Line.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Mesh.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Bone.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/SkinnedMesh.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Ribbon.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/Sound.js"></script>
|
||||
<script type="text/javascript" src="../src/objects/LOD.js"></script>
|
||||
<script type="text/javascript" src="../src/scenes/Scene.js"></script>
|
||||
<script type="text/javascript" src="../src/scenes/Fog.js"></script>
|
||||
<script type="text/javascript" src="../src/scenes/FogExp2.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/Projector.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/DOMRenderer.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/CanvasRenderer.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/SVGRenderer.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/WebGLShaders.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/WebGLRenderer.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/SoundRenderer.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableVertex.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableFace3.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableFace4.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableObject.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableParticle.js"></script>
|
||||
<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/GeometryUtils.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/ImageUtils.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/SceneUtils.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/ShaderUtils.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/cameras/QuakeCamera.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/cameras/PathCamera.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Cube.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Cylinder.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Icosahedron.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Lathe.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Plane.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Sphere.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/Torus.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/geometries/TorusKnot.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/io/Loader.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/io/JSONLoader.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/io/BinaryLoader.js"></script>
|
||||
<script type="text/javascript" src="../src/extras/objects/MarchingCubes.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Detector.js"></script>
|
||||
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
|
||||
<script type="text/javascript" src="js/Stats.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
||||
|
||||
var SCREEN_WIDTH = window.innerWidth;
|
||||
var SCREEN_HEIGHT = window.innerHeight;
|
||||
|
||||
var container,stats;
|
||||
|
||||
var camera, scene, loaded;
|
||||
var renderer;
|
||||
|
||||
var mesh, zmesh, geometry;
|
||||
|
||||
var mouseX = 0, mouseY = 0;
|
||||
|
||||
var windowHalfX = window.innerWidth / 2;
|
||||
var windowHalfY = window.innerHeight / 2;
|
||||
|
||||
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function $( id ) {
|
||||
|
||||
return document.getElementById( id );
|
||||
|
||||
}
|
||||
|
||||
function handle_update( result, pieces ) {
|
||||
|
||||
refreshSceneView( result );
|
||||
renderer.initWebGLObjects( result.scene );
|
||||
|
||||
var m, material, count = 0;
|
||||
|
||||
for ( m in result.materials ) {
|
||||
|
||||
material = result.materials[ m ];
|
||||
if ( ! ( material instanceof THREE.MeshFaceMaterial ) ) {
|
||||
|
||||
if( !material.program ) {
|
||||
|
||||
console.log(m);
|
||||
renderer.initMaterial( material, result.scene.lights, result.scene.fog );
|
||||
|
||||
count += 1;
|
||||
if( count > pieces ) {
|
||||
|
||||
//console.log("xxxxxxxxx");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
container = document.createElement( 'div' );
|
||||
document.body.appendChild( container );
|
||||
|
||||
var loadScene = createLoadScene();
|
||||
scene = loadScene.scene;
|
||||
camera = loadScene.camera;
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
||||
renderer.domElement.style.position = "relative";
|
||||
container.appendChild( renderer.domElement );
|
||||
|
||||
stats = new Stats();
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.top = '0px';
|
||||
stats.domElement.style.right = '0px';
|
||||
stats.domElement.style.zIndex = 100;
|
||||
container.appendChild( stats.domElement );
|
||||
|
||||
$( "start" ).addEventListener( 'click', onStartClick, false );
|
||||
|
||||
var callback_progress = function( progress, result ) {
|
||||
|
||||
var bar = 250,
|
||||
total = progress.total_models + progress.total_textures,
|
||||
loaded = progress.loaded_models + progress.loaded_textures;
|
||||
|
||||
if ( total )
|
||||
bar = Math.floor( bar * loaded / total );
|
||||
|
||||
$( "bar" ).style.width = bar + "px";
|
||||
|
||||
count = 0;
|
||||
for ( var m in result.materials ) count++;
|
||||
|
||||
handle_update( result, Math.floor( count/total ) );
|
||||
|
||||
}
|
||||
|
||||
var callback_sync = function( result ) {
|
||||
|
||||
/*
|
||||
|
||||
// uncomment to see progressive scene loading
|
||||
|
||||
scene = result.scene;
|
||||
camera = result.currentCamera;
|
||||
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
renderer.setClearColor( result.bgColor, result.bgAlpha );
|
||||
|
||||
*/
|
||||
|
||||
//handle_update( result, 1 );
|
||||
|
||||
}
|
||||
|
||||
var callback_async = function( result ) {
|
||||
|
||||
loaded = result;
|
||||
|
||||
$( "message" ).style.display = "none";
|
||||
$( "progressbar" ).style.display = "none";
|
||||
$( "start" ).style.display = "block";
|
||||
$( "start" ).className = "enabled";
|
||||
|
||||
handle_update( result, 1 );
|
||||
|
||||
}
|
||||
|
||||
$( "progress" ).style.display = "block";
|
||||
SceneUtils.loadScene( "obj/blenderscene/scene.js", callback_sync, callback_async, callback_progress );
|
||||
|
||||
$( "plus_exp" ).addEventListener( 'click', createToggle( "exp" ), false );
|
||||
|
||||
}
|
||||
|
||||
function setButtonActive( id ) {
|
||||
|
||||
$( "start" ).style.backgroundColor = "green";
|
||||
|
||||
}
|
||||
|
||||
function onStartClick() {
|
||||
|
||||
$( "progress" ).style.display = "none";
|
||||
|
||||
scene = loaded.scene;
|
||||
camera = loaded.currentCamera;
|
||||
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
renderer.setClearColor( loaded.bgColor, loaded.bgAlpha );
|
||||
|
||||
}
|
||||
|
||||
function onDocumentMouseMove(event) {
|
||||
|
||||
mouseX = ( event.clientX - windowHalfX );
|
||||
mouseY = ( event.clientY - windowHalfY );
|
||||
|
||||
}
|
||||
|
||||
function createLoadScene() {
|
||||
|
||||
var result = {
|
||||
|
||||
scene: new THREE.Scene(),
|
||||
camera: new THREE.Camera( 65, window.innerWidth / window.innerHeight, 1, 1000 )
|
||||
|
||||
};
|
||||
|
||||
result.camera.position.z = 100;
|
||||
|
||||
var object, geometry, material, light, count = 500, range = 200;
|
||||
|
||||
material = new THREE.MeshLambertMaterial( { color:0xffffff } );
|
||||
geometry = new Cube( 5, 5, 5 );
|
||||
|
||||
for( var i = 0; i < count; i++ ) {
|
||||
|
||||
object = new THREE.Mesh( geometry, material );
|
||||
object.position.x = ( Math.random() - 0.5 ) * range;
|
||||
object.position.y = ( Math.random() - 0.5 ) * range;
|
||||
object.position.z = ( Math.random() - 0.5 ) * range;
|
||||
object.rotation.x = Math.random() * 6;
|
||||
object.rotation.y = Math.random() * 6;
|
||||
object.rotation.z = Math.random() * 6;
|
||||
object.matrixAutoUpdate = false;
|
||||
object.updateMatrix();
|
||||
result.scene.addObject( object );
|
||||
|
||||
}
|
||||
|
||||
result.scene.matrixAutoUpdate = false;
|
||||
|
||||
light = new THREE.PointLight( 0xffffff );
|
||||
result.scene.addLight( light );
|
||||
|
||||
light = new THREE.DirectionalLight( 0x111111 );
|
||||
light.position.x = 1;
|
||||
result.scene.addLight( light );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function animate() {
|
||||
|
||||
requestAnimationFrame( animate );
|
||||
|
||||
render();
|
||||
stats.update();
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
camera.position.x += ( mouseX - camera.position.x ) * .001;
|
||||
camera.position.y += ( - mouseY - camera.position.y ) * .001;
|
||||
|
||||
renderer.render( scene, camera );
|
||||
|
||||
}
|
||||
|
||||
function log( text ) {
|
||||
|
||||
var e = $("log");
|
||||
e.innerHTML = text + "<br/>" + e.innerHTML;
|
||||
|
||||
}
|
||||
|
||||
// Scene explorer user interface
|
||||
|
||||
function toggle( id ) {
|
||||
|
||||
var scn = $( "section_" + id ).style,
|
||||
btn = $( "plus_" + id );
|
||||
|
||||
if ( scn.display == "block" ) {
|
||||
|
||||
scn.display = "none";
|
||||
btn.innerHTML = "[+]";
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
scn.display = "block";
|
||||
btn.innerHTML = "[-]";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createToggle( label ) { return function() { toggle( label ) } };
|
||||
|
||||
function refreshSceneView( result ) {
|
||||
|
||||
$( "section_exp" ).innerHTML = generateSceneView( result );
|
||||
|
||||
var config = [ "obj", "geo", "mat", "tex", "lit", "cam" ];
|
||||
|
||||
for ( var i = 0; i < config.length; i++ )
|
||||
$( "plus_" + config[i] ).addEventListener( 'click', createToggle( config[i] ), false );
|
||||
|
||||
}
|
||||
|
||||
function generateSection( label, id, objects ) {
|
||||
|
||||
var html = "";
|
||||
|
||||
html += "<h3><a id='plus_" + id + "' href='#'>[+]</a> " + label + "</h3>";
|
||||
html += "<div id='section_" + id + "' class='part'>";
|
||||
|
||||
for( var o in objects ) {
|
||||
|
||||
html += o + "<br/>";
|
||||
|
||||
}
|
||||
html += "</div>";
|
||||
|
||||
return html;
|
||||
|
||||
}
|
||||
|
||||
function generateSceneView( result ) {
|
||||
|
||||
var config = [
|
||||
[ "Objects", "obj", result.objects ],
|
||||
[ "Geometries", "geo", result.geometries ],
|
||||
[ "Materials", "mat", result.materials ],
|
||||
[ "Textures", "tex", result.textures ],
|
||||
[ "Lights", "lit", result.lights ],
|
||||
[ "Cameras", "cam", result.cameras ]
|
||||
];
|
||||
|
||||
var html = "";
|
||||
|
||||
for ( var i = 0; i < config.length; i++ )
|
||||
html += generateSection( config[i][0], config[i][1], config[i][2] );
|
||||
|
||||
return html;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -35,13 +35,14 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
|
||||
|
||||
filename_ext = ".js"
|
||||
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers to the exported mesh", default=True)
|
||||
option_flip_yz = BoolProperty(name="Flip YZ", description="Flip YZ", default=True)
|
||||
use_normals = BoolProperty(name="Normals", description="Export normals", default=True)
|
||||
use_colors = BoolProperty(name="Colors", description="Export vertex colors", default=True)
|
||||
use_uv_coords = BoolProperty(name="UVs", description="Export texture coordinates", default=True)
|
||||
option_export_scene = BoolProperty(name="Scene", description="Export scene", default=True)
|
||||
|
||||
align_types = [("None","None","None"), ("Center","Center","Center"), ("Bottom","Bottom","Bottom"), ("Top","Top","Top")]
|
||||
align_model = EnumProperty(name="Align model", description="Align model", items=align_types, default="Center")
|
||||
align_model = EnumProperty(name="Align model", description="Align model", items=align_types, default="None")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -61,15 +62,24 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
|
||||
layout = self.layout
|
||||
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "use_modifiers")
|
||||
row.prop(self.properties, "option_export_scene")
|
||||
layout.separator()
|
||||
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "option_flip_yz")
|
||||
layout.separator()
|
||||
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "align_model")
|
||||
layout.separator()
|
||||
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "use_normals")
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "use_colors")
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "use_uv_coords")
|
||||
row = layout.row()
|
||||
row.prop(self.properties, "align_model")
|
||||
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
Blender exporter for Three.js (ASCII JSON format).
|
||||
|
||||
TODO
|
||||
- model alignment
|
||||
- export scene
|
||||
- copy used images to folder where exported file goes
|
||||
- export all selected meshes
|
||||
- binary format
|
||||
"""
|
||||
|
||||
@@ -42,13 +41,149 @@ import random
|
||||
# Configuration
|
||||
# #####################################################
|
||||
|
||||
# default colors for debugging (each material gets one distinct color):
|
||||
DEFAULTS = {
|
||||
"bgcolor" : [0, 0, 0],
|
||||
"bgalpha" : 1.0,
|
||||
|
||||
"camera" :
|
||||
{
|
||||
"name" : "default_camera",
|
||||
"type" : "perspective",
|
||||
"near" : 1,
|
||||
"far" : 10000,
|
||||
"fov" : 60,
|
||||
"aspect": 1.333,
|
||||
"position" : [0, 0, 10],
|
||||
"target" : [0, 0, 0]
|
||||
},
|
||||
|
||||
"light" :
|
||||
{
|
||||
"name" : "default_light",
|
||||
"type" : "directional",
|
||||
"direction" : [0,1,1],
|
||||
"color" : [1,1,1],
|
||||
"intensity" : 0.8
|
||||
}
|
||||
}
|
||||
|
||||
# default colors for debugging (each material gets one distinct color):
|
||||
# white, red, green, blue, yellow, cyan, magenta
|
||||
COLORS = [0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee, 0xeeee00, 0x00eeee, 0xee00ee]
|
||||
|
||||
|
||||
# #####################################################
|
||||
# Templates
|
||||
# Templates - scene
|
||||
# #####################################################
|
||||
TEMPLATE_SCENE_ASCII = """\
|
||||
// Converted from: %(fname)s
|
||||
// File generated with Blender 2.56 Exporter
|
||||
// https://github.com/alteredq/three.js/tree/master/utils/exporters/blender/
|
||||
|
||||
|
||||
var scene = {
|
||||
|
||||
"type" : "scene",
|
||||
"urlBaseType" : "relativeToScene",
|
||||
|
||||
%(sections)s
|
||||
|
||||
"defaults" :
|
||||
{
|
||||
"bgcolor" : %(bgcolor)s,
|
||||
"bgalpha" : %(bgalpha)f,
|
||||
"camera" : %(defcamera)s
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
postMessage( scene );
|
||||
|
||||
"""
|
||||
|
||||
TEMPLATE_SECTION = """
|
||||
"%s" :
|
||||
{
|
||||
%s
|
||||
},
|
||||
"""
|
||||
|
||||
TEMPLATE_OBJECT = """\
|
||||
%(object_id)s : {
|
||||
"geometry" : %(geometry_id)s,
|
||||
"materials" : [ %(material_id)s ],
|
||||
"position" : %(position)s,
|
||||
"rotation" : %(rotation)s,
|
||||
"quaternion": %(quaternion)s,
|
||||
"scale" : %(scale)s,
|
||||
"visible" : true
|
||||
}"""
|
||||
|
||||
TEMPLATE_GEOMETRY = """\
|
||||
%(geometry_id)s : {
|
||||
"type" : "ascii_mesh",
|
||||
"url" : %(model_file)s
|
||||
}"""
|
||||
|
||||
TEMPLATE_TEXTURE = """\
|
||||
%(texture_id)s : {
|
||||
"url": %(texture_file)s
|
||||
}"""
|
||||
|
||||
TEMPLATE_MATERIAL_SCENE = """\
|
||||
%(material_id)s : {
|
||||
"type": %(type)s,
|
||||
"parameters": { %(parameters)s }
|
||||
}"""
|
||||
|
||||
TEMPLATE_CAMERA_PERSPECTIVE = """\
|
||||
%(camera_id)s : {
|
||||
"type" : "perspective",
|
||||
"fov" : %(fov)f,
|
||||
"aspect": %(aspect)f,
|
||||
"near" : %(near)f,
|
||||
"far" : %(far)f,
|
||||
"position": %(position)s,
|
||||
"target" : %(target)s
|
||||
}"""
|
||||
|
||||
TEMPLATE_CAMERA_ORTHO = """\
|
||||
%(camera_id)s: {
|
||||
"type" : "ortho",
|
||||
"left" : %(left)f,
|
||||
"right" : %(right)f,
|
||||
"top" : %(top)f,
|
||||
"bottom": %(bottom)f,
|
||||
"near" : %(near)f,
|
||||
"far" : %(far)f,
|
||||
"position": %(position)s,
|
||||
"target" : %(target)s
|
||||
}"""
|
||||
|
||||
TEMPLATE_LIGHT_DIRECTIONAL = """\
|
||||
%(light_id)s: {
|
||||
"type" : "directional",
|
||||
"direction" : %(direction)s,
|
||||
"color" : %(color)s,
|
||||
"intensity" : %(intensity).2f
|
||||
}"""
|
||||
|
||||
TEMPLATE_LIGHT_POINT = """\
|
||||
%(light_id)s: {
|
||||
"type" : "point",
|
||||
"position" : %(position)s,
|
||||
"color" : %(color)s
|
||||
"intensity" : %(intensity).3f
|
||||
}"""
|
||||
|
||||
TEMPLATE_VEC4 = '[ %f, %f, %f, %f ]'
|
||||
TEMPLATE_VEC3 = '[ %f, %f, %f ]'
|
||||
TEMPLATE_VEC2 = '[ %f, %f ]'
|
||||
TEMPLATE_STRING = '"%s"'
|
||||
TEMPLATE_HEX = "0x%06x"
|
||||
|
||||
# #####################################################
|
||||
# Templates - model
|
||||
# #####################################################
|
||||
TEMPLATE_FILE_ASCII = """\
|
||||
/*
|
||||
@@ -98,8 +233,11 @@ TEMPLATE_C = "0x%06x"
|
||||
# #####################################################
|
||||
# Utils
|
||||
# #####################################################
|
||||
def veckey3(x,y,z):
|
||||
return round(x, 6), round(y, 6), round(z, 6)
|
||||
|
||||
def veckey3d(v):
|
||||
return round(v.x, 6), round(v.y, 6), round(v.z, 6)
|
||||
return veckey3(v.x, v.y, v.z)
|
||||
|
||||
def veckey2d(v):
|
||||
return round(v[0], 6), round(v[1], 6)
|
||||
@@ -107,8 +245,13 @@ def veckey2d(v):
|
||||
def get_normal_indices(v, normals, mesh):
|
||||
n = []
|
||||
mv = mesh.vertices
|
||||
|
||||
for i in v:
|
||||
n.append( normals[veckey3d(mv[i].normal)] )
|
||||
normal = mv[i].normal
|
||||
key = veckey3d(normal)
|
||||
|
||||
n.append( normals[key] )
|
||||
|
||||
return n
|
||||
|
||||
def get_uv_indices(face_index, uvs, mesh):
|
||||
@@ -127,6 +270,24 @@ def get_color_indices(face_index, colors, mesh):
|
||||
c.append( colors[hexcolor(i)] )
|
||||
return c
|
||||
|
||||
def rgb2int(rgb):
|
||||
color = (int(rgb[0]*255) << 16) + (int(rgb[1]*255) << 8) + int(rgb[2]*255);
|
||||
return color
|
||||
|
||||
# #####################################################
|
||||
# Utils - files
|
||||
# #####################################################
|
||||
def write_file(fname, content):
|
||||
out = open(fname, "w")
|
||||
out.write(content)
|
||||
out.close()
|
||||
|
||||
def ensure_folder_exist(foldername):
|
||||
"""Create folder (with whole path) if it doesn't exist yet."""
|
||||
|
||||
if not os.access(foldername, os.R_OK|os.W_OK|os.X_OK):
|
||||
os.makedirs(foldername)
|
||||
|
||||
# #####################################################
|
||||
# Alignment
|
||||
# #####################################################
|
||||
@@ -231,7 +392,7 @@ def setBit(value, position, on):
|
||||
mask = ~(1 << position)
|
||||
return (value & mask)
|
||||
|
||||
def generate_face(f, faceIndex, normals, uvs, colors, mesh, use_normals, use_colors, use_uv_coords):
|
||||
def generate_face(f, faceIndex, normals, uvs, colors, mesh, use_normals, use_colors, use_uv_coords, flipyz):
|
||||
isTriangle = ( len(f.vertices) == 3 )
|
||||
|
||||
if isTriangle:
|
||||
@@ -315,7 +476,10 @@ def extract_vertex_normals(mesh, use_normals):
|
||||
|
||||
for f in mesh.faces:
|
||||
for v in f.vertices:
|
||||
key = veckey3d(mesh.vertices[v].normal)
|
||||
|
||||
normal = mesh.vertices[v].normal
|
||||
key = veckey3d(normal)
|
||||
|
||||
if key not in normals:
|
||||
normals[key] = count
|
||||
count += 1
|
||||
@@ -327,7 +491,7 @@ def generate_normals(normals, use_normals):
|
||||
return ""
|
||||
|
||||
chunks = []
|
||||
for key, index in sorted(normals.items(), key=operator.itemgetter(1)):
|
||||
for key, index in sorted(normals.items(), key = operator.itemgetter(1)):
|
||||
chunks.append(key)
|
||||
|
||||
return ",".join(generate_normal(n) for n in chunks)
|
||||
@@ -441,7 +605,7 @@ def value2string(v):
|
||||
return str(v).lower()
|
||||
return str(v)
|
||||
|
||||
def generate_materials(mtl, materials, use_colors):
|
||||
def generate_materials(mtl, materials, use_colors, draw_type):
|
||||
"""Generate JS array of materials objects
|
||||
"""
|
||||
|
||||
@@ -458,6 +622,10 @@ def generate_materials(mtl, materials, use_colors):
|
||||
mtl[m]['DbgColor'] = generate_color(index)
|
||||
mtl[m]['vertexColors'] = use_colors
|
||||
|
||||
if draw_type in [ "BOUNDS", "WIRE" ]:
|
||||
mtl[m]['wireframe'] = True
|
||||
mtl[m]['DbgColor'] = 0xff0000
|
||||
|
||||
mtl_raw = ",\n".join(['\t"%s" : %s' % (n, value2string(v)) for n,v in sorted(mtl[m].items())])
|
||||
mtl_string = "\t{\n%s\n\t}" % mtl_raw
|
||||
mtl_array.append([index, mtl_string])
|
||||
@@ -505,7 +673,7 @@ def extract_materials(mesh, scene):
|
||||
|
||||
return materials
|
||||
|
||||
def generate_materials_string(mesh, scene, use_colors):
|
||||
def generate_materials_string(mesh, scene, use_colors, draw_type):
|
||||
|
||||
random.seed(42) # to get well defined color order for debug materials
|
||||
|
||||
@@ -522,19 +690,21 @@ def generate_materials_string(mesh, scene, use_colors):
|
||||
materials = { 'default':0 }
|
||||
|
||||
# default dummy materials
|
||||
|
||||
mtl = generate_mtl(materials)
|
||||
|
||||
# extract real materials from the mesh
|
||||
|
||||
mtl.update(extract_materials(mesh, scene))
|
||||
|
||||
return generate_materials(mtl, materials, use_colors)
|
||||
return generate_materials(mtl, materials, use_colors, draw_type)
|
||||
|
||||
# #####################################################
|
||||
# ASCII exporter
|
||||
# #####################################################
|
||||
def generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, align_model):
|
||||
def generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, align_model, flipyz, draw_type):
|
||||
|
||||
vertices = mesh.vertices[:]
|
||||
vertices = mesh.vertices[:]
|
||||
|
||||
if align_model == 1:
|
||||
center(vertices)
|
||||
@@ -547,7 +717,7 @@ def generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, al
|
||||
colors, ncolor = extract_vertex_colors(mesh, use_colors)
|
||||
uvs, nuv = extract_uvs(mesh, use_uv_coords)
|
||||
|
||||
mstring, nmaterial = generate_materials_string(mesh, scene, use_colors)
|
||||
mstring, nmaterial = generate_materials_string(mesh, scene, use_colors, draw_type)
|
||||
|
||||
text = TEMPLATE_FILE_ASCII % {
|
||||
"nvertex" : len(mesh.vertices),
|
||||
@@ -565,46 +735,49 @@ def generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, al
|
||||
|
||||
"vertices" : ",".join(generate_vertex(v) for v in vertices),
|
||||
|
||||
"faces" : ",".join(generate_face(f, i, normals, uvs, colors, mesh, use_normals, use_colors, use_uv_coords) for i, f in enumerate(mesh.faces))
|
||||
"faces" : ",".join(generate_face(f, i, normals, uvs, colors, mesh, use_normals, use_colors, use_uv_coords, flipyz) for i, f in enumerate(mesh.faces))
|
||||
|
||||
}
|
||||
|
||||
return text
|
||||
|
||||
# #####################################################
|
||||
# Main
|
||||
# Utils
|
||||
# #####################################################
|
||||
def save(operator, context, filepath="", use_modifiers=True, use_normals=True, use_colors=True, use_uv_coords=True, align_model=1):
|
||||
def ensure_extension(filepath, extension):
|
||||
if not filepath.lower().endswith(extension):
|
||||
filepath += extension
|
||||
return filepath
|
||||
|
||||
def generate_mesh_filename(meshname, filepath):
|
||||
normpath = os.path.normpath(filepath)
|
||||
path, ext = os.path.splitext(normpath)
|
||||
return "%s.%s%s" % (path, meshname, ext)
|
||||
|
||||
# #####################################################
|
||||
# Export single mesh
|
||||
# #####################################################
|
||||
def export_mesh(obj, scene, filepath, use_normals, use_colors, use_uv_coords, align_model, flipyz, export_single_model):
|
||||
"""Export single mesh"""
|
||||
|
||||
def rvec3d(v):
|
||||
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||
|
||||
def rvec2d(v):
|
||||
return round(v[0], 6), round(v[1], 6)
|
||||
|
||||
scene = context.scene
|
||||
obj = context.object
|
||||
|
||||
if not filepath.lower().endswith('.js'):
|
||||
filepath += '.js'
|
||||
|
||||
if not obj:
|
||||
raise Exception("Error, Select 1 active object")
|
||||
|
||||
if scene.objects.active:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if use_modifiers:
|
||||
mesh = obj.create_mesh(scene, True, 'PREVIEW')
|
||||
else:
|
||||
mesh = obj.data
|
||||
# collapse modifiers into mesh
|
||||
|
||||
mesh = obj.create_mesh(scene, True, 'RENDER')
|
||||
|
||||
if not mesh:
|
||||
raise Exception("Error, could not get mesh data from active object")
|
||||
raise Exception("Error, could not get mesh data from object [%s]" % obj.name)
|
||||
|
||||
# that's what Blender's native export_obj.py does
|
||||
x_rot = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
|
||||
mesh.transform(x_rot * obj.matrix_world)
|
||||
# to flip YZ
|
||||
|
||||
X_ROT = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
|
||||
|
||||
if export_single_model:
|
||||
mesh.transform(X_ROT * obj.matrix_world)
|
||||
else:
|
||||
mesh.transform(X_ROT)
|
||||
|
||||
mesh.calc_normals()
|
||||
|
||||
faceUV = (len(mesh.uv_textures) > 0)
|
||||
@@ -627,14 +800,412 @@ def save(operator, context, filepath="", use_modifiers=True, use_normals=True, u
|
||||
if not active_col_layer:
|
||||
use_colors = False
|
||||
|
||||
text = generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, align_model)
|
||||
file = open(filepath, 'w')
|
||||
file.write(text)
|
||||
file.close()
|
||||
text = generate_ascii_model(mesh, scene, use_normals, use_colors, use_uv_coords, align_model, flipyz, obj.draw_type)
|
||||
write_file(filepath, text)
|
||||
|
||||
# remove temp mesh
|
||||
|
||||
bpy.data.meshes.remove(mesh)
|
||||
|
||||
print("writing", filepath, "done")
|
||||
|
||||
|
||||
# #####################################################
|
||||
# Export scene
|
||||
# #####################################################
|
||||
def generate_vec4(vec):
|
||||
return TEMPLATE_VEC4 % (vec[0], vec[1], vec[2], vec[3])
|
||||
|
||||
if use_modifiers:
|
||||
bpy.data.meshes.remove(mesh)
|
||||
def generate_vec3(vec):
|
||||
return TEMPLATE_VEC3 % (vec[0], vec[1], vec[2])
|
||||
|
||||
def generate_vec2(vec):
|
||||
return TEMPLATE_VEC2 % (vec[0], vec[1])
|
||||
|
||||
def generate_hex(number):
|
||||
return TEMPLATE_HEX % number
|
||||
|
||||
def generate_string(s):
|
||||
return TEMPLATE_STRING % s
|
||||
|
||||
def generate_section(label, content):
|
||||
return TEMPLATE_SECTION % (label, content)
|
||||
|
||||
def get_mesh_filename(mesh):
|
||||
object_id = mesh["data"]["name"]
|
||||
filename = "%s.js" % sanitize(object_id)
|
||||
return filename
|
||||
|
||||
def generate_material_id_list(materials):
|
||||
chunks = []
|
||||
for material in materials:
|
||||
chunks.append(material.name)
|
||||
|
||||
return ",".join(chunks)
|
||||
|
||||
def generate_objects(data):
|
||||
chunks = []
|
||||
|
||||
for obj in data["objects"]:
|
||||
if obj.type == "MESH":
|
||||
object_id = obj.name
|
||||
|
||||
if len(obj.modifiers) > 0:
|
||||
geo_name = obj.name
|
||||
else:
|
||||
geo_name = obj.data.name
|
||||
|
||||
geometry_id = "geo_%s" % geo_name
|
||||
|
||||
material_id = generate_material_id_list(obj.material_slots)
|
||||
|
||||
#position = obj.location
|
||||
#rotation = obj.rotation_euler
|
||||
scale = obj.scale
|
||||
quaternion = obj.rotation_quaternion
|
||||
|
||||
position = [obj.location.x, obj.location.z, -obj.location.y]
|
||||
rotation = [obj.rotation_euler.x, -obj.rotation_euler.y, -obj.rotation_euler.z]
|
||||
#quaternion = obj.rotation_euler.to_quat()
|
||||
scale = [obj.scale.x, obj.scale.z, obj.scale.y]
|
||||
|
||||
material_string = ""
|
||||
if material_id:
|
||||
material_string = generate_string(material_id)
|
||||
|
||||
object_string = TEMPLATE_OBJECT % {
|
||||
"object_id" : generate_string(object_id),
|
||||
"geometry_id" : generate_string(geometry_id),
|
||||
"material_id" : material_string,
|
||||
"position" : generate_vec3(position),
|
||||
"rotation" : generate_vec3(rotation),
|
||||
"quaternion" : generate_vec4(quaternion),
|
||||
"scale" : generate_vec3(scale)
|
||||
}
|
||||
chunks.append(object_string)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def generate_geometries(data):
|
||||
chunks = []
|
||||
|
||||
geo_set = set()
|
||||
|
||||
for obj in data["objects"]:
|
||||
if obj.type == "MESH":
|
||||
|
||||
if len(obj.modifiers) > 0:
|
||||
name = obj.name
|
||||
else:
|
||||
name = obj.data.name
|
||||
|
||||
if name not in geo_set:
|
||||
|
||||
geometry_id = "geo_%s" % name
|
||||
model_filename = os.path.basename(generate_mesh_filename(name, data["filepath"]))
|
||||
|
||||
geometry_string = TEMPLATE_GEOMETRY % {
|
||||
"geometry_id" : generate_string(geometry_id),
|
||||
"model_file" : generate_string(model_filename)
|
||||
}
|
||||
chunks.append(geometry_string)
|
||||
|
||||
geo_set.add(name)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def generate_textures_scene(data):
|
||||
chunks = []
|
||||
|
||||
# TODO: extract just textures actually used by some objects in the scene
|
||||
|
||||
for img in bpy.data.images:
|
||||
|
||||
texture_id = img.name
|
||||
texture_file = extract_texture_filename(img)
|
||||
|
||||
texture_string = TEMPLATE_TEXTURE % {
|
||||
"texture_id" : generate_string(texture_id),
|
||||
"texture_file" : generate_string(texture_file)
|
||||
}
|
||||
chunks.append(texture_string)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def extract_texture_filename(image):
|
||||
fn = bpy.path.abspath(image.filepath)
|
||||
fn = os.path.normpath(fn)
|
||||
fn_strip = os.path.basename(fn)
|
||||
return fn_strip
|
||||
|
||||
def extract_material_data(m):
|
||||
world = bpy.context.scene.world
|
||||
|
||||
material = { 'name': m.name }
|
||||
|
||||
material['colorDiffuse'] = [m.diffuse_intensity * m.diffuse_color[0],
|
||||
m.diffuse_intensity * m.diffuse_color[1],
|
||||
m.diffuse_intensity * m.diffuse_color[2]]
|
||||
|
||||
material['colorSpecular'] = [m.specular_intensity * m.specular_color[0],
|
||||
m.specular_intensity * m.specular_color[1],
|
||||
m.specular_intensity * m.specular_color[2]]
|
||||
|
||||
material['colorAmbient'] = [m.ambient * world.ambient_color[0],
|
||||
m.ambient * world.ambient_color[1],
|
||||
m.ambient * world.ambient_color[2]]
|
||||
|
||||
material['transparency'] = m.alpha
|
||||
|
||||
# not sure about mapping values to Blinn-Phong shader
|
||||
# Blender uses INT from [1,511] with default 0
|
||||
# http://www.blender.org/documentation/blender_python_api_2_54_0/bpy.types.Material.html#bpy.types.Material.specular_hardness
|
||||
|
||||
material["specularCoef"] = m.specular_hardness
|
||||
|
||||
material['mapDiffuse'] = ""
|
||||
material['mapLight'] = ""
|
||||
material['mapNormal'] = ""
|
||||
|
||||
# just take first textures of each, for the moment three.js materials can't handle more
|
||||
|
||||
for i in range(len(m.texture_slots)):
|
||||
ts = m.texture_slots[i]
|
||||
if ts:
|
||||
t = ts.texture
|
||||
if ts.use and t.type == 'IMAGE':
|
||||
name = t.image.name
|
||||
|
||||
if t.use_normal_map:
|
||||
material['mapNormal'] = name
|
||||
else:
|
||||
if not material['mapDiffuse']:
|
||||
material['mapDiffuse'] = name
|
||||
else:
|
||||
material['mapLight'] = name
|
||||
|
||||
if material['mapDiffuse'] and material['mapNormal'] and material['mapLight']:
|
||||
break
|
||||
|
||||
if m.specular_intensity > 0.0 and (m.specular_color[0] > 0 or m.specular_color[1] > 0 or m.specular_color[2] > 0):
|
||||
material['shading'] = "Phong"
|
||||
else:
|
||||
material['shading'] = "Lambert"
|
||||
|
||||
return material
|
||||
|
||||
def generate_material_string(material):
|
||||
type_map = {
|
||||
"Lambert" : "MeshLambertMaterial",
|
||||
"Phong" : "MeshPhongMaterial"
|
||||
}
|
||||
|
||||
material_id = material["name"]
|
||||
shading = material["shading"]
|
||||
material_type = type_map.get(shading, "MeshBasicMaterial")
|
||||
|
||||
parameters = "color: %s" % generate_hex(rgb2int(material["colorDiffuse"]))
|
||||
parameters += ", opacity: %.2f" % material["transparency"]
|
||||
|
||||
if shading == "Phong":
|
||||
parameters += ", ambient: %s" % generate_hex(rgb2int(material["colorAmbient"]))
|
||||
parameters += ", specular: %s" % generate_hex(rgb2int(material["colorSpecular"]))
|
||||
parameters += ", shininess: %.1f" % material["specularCoef"]
|
||||
|
||||
colorMap = material['mapDiffuse']
|
||||
lightMap = material['mapLight']
|
||||
normalMap = material['mapNormal']
|
||||
|
||||
if colorMap:
|
||||
parameters += ", map: %s" % generate_string(colorMap)
|
||||
if lightMap:
|
||||
parameters += ", lightMap: %s" % generate_string(lightMap)
|
||||
if normalMap:
|
||||
parameters += ", normalMap: %s" % generate_string(normalMap)
|
||||
|
||||
material_string = TEMPLATE_MATERIAL_SCENE % {
|
||||
"material_id" : generate_string(material_id),
|
||||
"type" : generate_string(material_type),
|
||||
"parameters" : parameters
|
||||
}
|
||||
|
||||
return material_string
|
||||
|
||||
def generate_materials_scene(data):
|
||||
chunks = []
|
||||
|
||||
# TODO: extract just materials actually used by some objects in the scene
|
||||
|
||||
for m in bpy.data.materials:
|
||||
material = extract_material_data(m)
|
||||
material_string = generate_material_string(material)
|
||||
chunks.append(material_string)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def generate_cameras(data):
|
||||
cameras = data.get("cameras", [])
|
||||
if not cameras:
|
||||
cameras.append(DEFAULTS["camera"])
|
||||
|
||||
chunks = []
|
||||
for camera in cameras:
|
||||
|
||||
if camera["type"] == "perspective":
|
||||
camera_string = TEMPLATE_CAMERA_PERSPECTIVE % {
|
||||
"camera_id" : generate_string(camera["name"]),
|
||||
"fov" : camera["fov"],
|
||||
"aspect" : camera["aspect"],
|
||||
"near" : camera["near"],
|
||||
"far" : camera["far"],
|
||||
"position" : generate_vec3(camera["position"]),
|
||||
"target" : generate_vec3(camera["target"])
|
||||
}
|
||||
|
||||
elif camera["type"] == "ortho":
|
||||
camera_string = TEMPLATE_CAMERA_ORTHO % {
|
||||
"camera_id" : generate_string(camera["name"]),
|
||||
"left" : camera["left"],
|
||||
"right" : camera["right"],
|
||||
"top" : camera["top"],
|
||||
"bottom" : camera["bottom"],
|
||||
"near" : camera["near"],
|
||||
"far" : camera["far"],
|
||||
"position" : generate_vec3(camera["position"]),
|
||||
"target" : generate_vec3(camera["target"])
|
||||
}
|
||||
|
||||
chunks.append(camera_string)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def generate_lights(data):
|
||||
lights = data.get("lights", [])
|
||||
if not lights:
|
||||
lights.append(DEFAULTS["light"])
|
||||
|
||||
chunks = []
|
||||
for light in lights:
|
||||
|
||||
if light["type"] == "directional":
|
||||
light_string = TEMPLATE_LIGHT_DIRECTIONAL % {
|
||||
"light_id" : generate_string(light["name"]),
|
||||
"direction" : generate_vec3(light["direction"]),
|
||||
"color" : generate_hex(rgb2int(light["color"])),
|
||||
"intensity" : light["intensity"]
|
||||
}
|
||||
|
||||
elif light["type"] == "point":
|
||||
light_string = TEMPLATE_LIGHT_POINT % {
|
||||
"light_id" : generate_string(light["name"]),
|
||||
"position" : generate_vec3(light["position"]),
|
||||
"color" : generate_hex(rgb2int(light["color"])),
|
||||
"intensity" : light["intensity"]
|
||||
}
|
||||
|
||||
chunks.append(light_string)
|
||||
|
||||
return ",\n\n".join(chunks)
|
||||
|
||||
def generate_ascii_scene(data):
|
||||
objects = generate_objects(data)
|
||||
geometries = generate_geometries(data)
|
||||
textures = generate_textures_scene(data)
|
||||
materials = generate_materials_scene(data)
|
||||
cameras = generate_cameras(data)
|
||||
lights = generate_lights(data)
|
||||
|
||||
sections = [
|
||||
["objects", objects],
|
||||
["geometries", geometries],
|
||||
["textures", textures],
|
||||
["materials", materials],
|
||||
["cameras", cameras],
|
||||
["lights", lights]
|
||||
]
|
||||
|
||||
chunks = []
|
||||
for label, content in sections:
|
||||
if content:
|
||||
chunks.append(generate_section(label, content))
|
||||
|
||||
sections_string = "\n".join(chunks)
|
||||
|
||||
default_camera = "default_camera"
|
||||
|
||||
parameters = {
|
||||
"fname" : data["source_file"],
|
||||
"sections" : sections_string,
|
||||
"bgcolor" : generate_vec3(DEFAULTS["bgcolor"]),
|
||||
"bgalpha" : DEFAULTS["bgalpha"],
|
||||
"defcamera" : generate_string(default_camera)
|
||||
}
|
||||
|
||||
text = TEMPLATE_SCENE_ASCII % parameters
|
||||
|
||||
return text
|
||||
|
||||
def export_scene(scene, filepath, flipyz):
|
||||
|
||||
source_file = os.path.basename(bpy.data.filepath)
|
||||
|
||||
scene_text = ""
|
||||
data = {
|
||||
"scene" : scene,
|
||||
"objects" : scene.objects,
|
||||
"source_file" : source_file,
|
||||
"filepath" : filepath,
|
||||
"flipyz" : flipyz
|
||||
}
|
||||
scene_text += generate_ascii_scene(data)
|
||||
|
||||
write_file(filepath, scene_text)
|
||||
|
||||
# #####################################################
|
||||
# Main
|
||||
# #####################################################
|
||||
def save(operator, context, filepath = "", option_flip_yz = True, use_normals = True, use_colors = True, use_uv_coords = True, align_model = 0, option_export_scene = True):
|
||||
|
||||
filepath = ensure_extension(filepath, '.js')
|
||||
|
||||
scene = context.scene
|
||||
|
||||
if scene.objects.active:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if option_export_scene:
|
||||
|
||||
export_scene(scene, filepath, option_flip_yz)
|
||||
|
||||
geo_set = set()
|
||||
|
||||
for obj in scene.objects:
|
||||
if obj.type == "MESH":
|
||||
|
||||
# create extra copy of geometry with applied modifiers
|
||||
# (if they exist)
|
||||
|
||||
if len(obj.modifiers) > 0:
|
||||
name = obj.name
|
||||
|
||||
# otherwise can share geometry
|
||||
|
||||
else:
|
||||
name = obj.data.name
|
||||
|
||||
if name not in geo_set:
|
||||
fname = generate_mesh_filename(name, filepath)
|
||||
export_mesh(obj, scene, fname, use_normals, use_colors, use_uv_coords, 0, option_flip_yz, False)
|
||||
|
||||
geo_set.add(name)
|
||||
|
||||
else:
|
||||
|
||||
obj = context.object
|
||||
if not obj:
|
||||
raise Exception("Error, Select 1 active object or select 'export scene'")
|
||||
|
||||
export_mesh(obj, scene, filepath, use_normals, use_colors, use_uv_coords, align_model, option_flip_yz, True)
|
||||
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
Reference in New Issue
Block a user