DUST3D 1.0 xml 0000000257
var SUBDIVED = document.createCheckInput("Subdived", false);
var MAX_RADIUS_OFFSET = document.createFloatInput("Max Radius Offset", 0.10, -1.0, 1.0);
var MAX_ORIGIN_OFFSET = document.createFloatInput("Max Origin Offset", 0.47, -1.0, 1.0);
var TREE_HEIGHT = document.createFloatInput("Height", 0.85, 0.1, 1.0);
var TRUNK_RADIUS = document.createFloatInput("Trunk Radius", 0.02, 0.01, 0.2);
var TRUNK_SEGMENTS = document.createIntInput("Trunk Segments", 15, 2, 30);
var TRUNK_COLOR = document.createColorInput("Trunk Color", "#939297");
var BRANCH_MIN_ANGLE = document.createFloatInput("Branch Min Angle", 10.72, 8, 30);
var BRANCH_MAX_ANGLE = document.createFloatInput("Branch Max Angle", 58.81, 50, 75);
var MAX_BRANCHES_PER_GROWTH = document.createIntInput("Max Branches", 7, 1, 7);
var BRANCH_LENGTH_MIN_RATIO = document.createFloatInput("Branch Length Min Ratio", 0.24, 0.2, 0.9);
var BRANCH_LENGTH_MAX_RATIO = document.createFloatInput("Branch Length Max Ratio", 0.78, 0.2, 0.9);
var LEAF_MIN_LENGTH = document.createFloatInput("Leaf Min Length", 0.05, 0.005, 0.1);
var LEAF_MAX_LENGTH = document.createFloatInput("Leaf Max Length", 0.08, 0.005, 0.2);
var LEAF_SEGMENTS = document.createIntInput("Leaf Segments", 5, 3, 6);
var LEAF_COLOR = document.createColorInput("Leaf Color", "#58834b");
var X = new THREE.Vector3( 1, 0, 0 );
var Y = new THREE.Vector3( 0, 1, 0 );
function createNode(part, origin, radius)
{
var node = document.createNode(part);
document.setAttribute(node, "x", origin.getComponent(0));
document.setAttribute(node, "y", origin.getComponent(1));
document.setAttribute(node, "z", origin.getComponent(2));
document.setAttribute(node, "radius", radius);
return node;
}
THREE.Vector3.prototype.random = function (maxOffset)
{
for (var i = 0; i < 3; ++i)
this.setComponent(i, this.getComponent(i) + maxOffset * Math.random());
return this;
};
function randInRange(min, max)
{
if (min > max) {
var tmp = min;
min = max;
max = tmp;
}
return (min + (max - min) * Math.random());
}
function createLeafCutFace()
{
var component = document.createComponent();
var part = document.createPart(component);
document.setAttribute(part, "target", "CutFace");
var predefinesCutFace = [
{radius:"0.005", x:"0.314637", y:"0.336525", z:"0.713406"},
{radius:"0.005", x:"0.343365", y:"0.340629", z:"0.713406"},
{radius:"0.005", x:"0.377565", y:"0.340629", z:"0.713406"},
{radius:"0.0159439", x:"0.402189", y:"0.341997", z:"0.713406"},
{radius:"0.005", x:"0.440492", y:"0.329685", z:"0.713406"},
{radius:"0.005", x:"0.473324", y:"0.317373", z:"0.713406"},
];
var previousNode = undefined;
for (var i = 0; i < predefinesCutFace.length; ++i) {
var node = createNode(part,
new THREE.Vector3(parseFloat(predefinesCutFace[i]["x"]),
parseFloat(predefinesCutFace[i]["y"]),
parseFloat(predefinesCutFace[i]["z"])),
parseFloat(predefinesCutFace[i]["radius"]));
if (undefined != previousNode)
document.connect(previousNode, node);
previousNode = node;
}
return part;
}
function getRandChildDirection(parentDirection)
{
var rotationAxis = parentDirection.clone().cross(X);
var degree = randInRange(BRANCH_MIN_ANGLE, BRANCH_MAX_ANGLE);
var branchRotateQuaternion = new THREE.Quaternion();
branchRotateQuaternion.setFromAxisAngle(rotationAxis, degree * (Math.PI / 180));
var rotatedDirection = parentDirection.clone().applyQuaternion(branchRotateQuaternion);
var distributeQuaternion = new THREE.Quaternion();
distributeQuaternion.setFromAxisAngle(Y, 360 * Math.random() * (Math.PI / 180));
rotatedDirection = rotatedDirection.applyQuaternion(distributeQuaternion);
return rotatedDirection;
}
var CUTFACE_PART_ID = document.attribute(createLeafCutFace(), "id");
function createLeaf(leafRootPosition, parentDirection)
{
var direction = getRandChildDirection(parentDirection);
var component = document.createComponent();
var part = document.createPart(component);
document.setAttribute(part, "color", LEAF_COLOR);
document.setAttribute(part, "cutFace", CUTFACE_PART_ID);
var length = randInRange(LEAF_MIN_LENGTH, LEAF_MAX_LENGTH);
var segments = LEAF_SEGMENTS;
var maxRadius = length / 3;
var toPosition = leafRootPosition.clone().add(direction.clone().multiplyScalar(length));
var previousNode = undefined;
for (var i = 0; i < segments; ++i) {
var alpha = (i + 0.0) / segments;
var origin = leafRootPosition.clone().lerp(toPosition, alpha);
var radiusFactor = 1.0 - 2 * Math.abs(alpha - 0.3);
var radius = maxRadius * radiusFactor;
var node = createNode(part, origin, radius);
if (undefined != previousNode)
document.connect(previousNode, node);
previousNode = node;
}
}
function createBranch(branchRootPosition, radius, length, segments, parentDirection, maxRadius)
{
var rotatedDirection = getRandChildDirection(parentDirection);
var branchEndPosition = branchRootPosition.clone().add(rotatedDirection.multiplyScalar(length));
createTrunk(branchRootPosition, radius, branchEndPosition, segments, maxRadius);
}
function shouldGrowBranch(alpha, alreadyGrowedNum)
{
var factor = alpha * Math.random();
if (factor > 0.5 && factor < 0.8) {
if (alreadyGrowedNum > 0)
return true;
if (Math.random() > 0.5)
return true;
}
return false;
}
function shouldGrowLeaf(alreadyGrowedNum)
{
var factor = Math.random();
if (factor > 0.5) {
if (alreadyGrowedNum > 0)
return true;
if (Math.random() > 0.5)
return true;
}
return false;
}
function createTrunk(fromPosition, fromRadius, toPosition, segments, maxRadius)
{
var component = document.createComponent();
var part = document.createPart(component);
if (SUBDIVED)
document.setAttribute(part, "subdived", "true");
document.setAttribute(part, "color", TRUNK_COLOR);
var previousNode = undefined;
var toRadius = fromRadius * 0.2;
var direction = toPosition.clone().sub(fromPosition).normalize();
var length = fromPosition.distanceTo(toPosition);
for (var i = 0; i < segments; ++i) {
var alpha = (i + 0.0) / segments;
var origin = fromPosition.clone().lerp(toPosition, alpha);
var radius = fromRadius * (1.0 - alpha) + toRadius * alpha;
radius += radius * MAX_RADIUS_OFFSET * Math.random();
if (undefined != maxRadius && radius > maxRadius)
radius = maxRadius;
var oldY = origin.y;
origin.random(length * 0.1 * MAX_ORIGIN_OFFSET);
origin.setY(oldY + radius * 0.5 * Math.random());
if (undefined != maxRadius && i == 0)
origin = fromPosition;
var node = createNode(part, origin, radius);
if (undefined != previousNode)
document.connect(previousNode, node);
var maxBranches = MAX_BRANCHES_PER_GROWTH * Math.random();
var alreadyGrowedBranchNum = 0;
var alreadyGrowedLeafNum = 0;
for (var j = 0; j < maxBranches; ++j) {
if (shouldGrowBranch(alpha, alreadyGrowedBranchNum)) {
var branchLength = length * randInRange(BRANCH_LENGTH_MIN_RATIO, BRANCH_LENGTH_MAX_RATIO);
var branchRadius = radius * 0.5;
var branchSegments = segments * (branchLength / length);
if (branchSegments >= 3 && branchRadius > TRUNK_RADIUS / 20) {
createBranch(origin, branchRadius, branchLength, branchSegments, direction, radius);
++alreadyGrowedBranchNum;
}
}
if (undefined != maxRadius && shouldGrowLeaf(alreadyGrowedLeafNum)) {
createLeaf(origin, direction);
++alreadyGrowedLeafNum;
}
}
previousNode = node;
}
}
var treeRootPosition = new THREE.Vector3(0.5, 1.0, 1.0);
var treeTopPosition = treeRootPosition.clone();
treeTopPosition.add((new THREE.Vector3(0, -1, 0)).multiplyScalar(TREE_HEIGHT));
document.setAttribute(document.canvas, "originX", 0.506767);
document.setAttribute(document.canvas, "originY", 0.615943);
document.setAttribute(document.canvas, "originZ", 1.08543);
createTrunk(treeRootPosition, TRUNK_RADIUS, treeTopPosition, TRUNK_SEGMENTS);