three.jsで影と重なった部分や物体が重なった部分の面積や体積を求めたいです
three.js を使って、物体同士が重なった部分や、影に隠れた部分の面積を求めたいですc
何かライブラリーなどはあるのでしょうか?
下記のサイトで webGL? を使った方法はあるみたいなのですが
どうも使い方がよくわからないので困っています。
何か参考になるサイトなどご存知ではないですか?
【追記】
例えばのコードを添付致します。
例えば物体によって面に作られた影の面積を求めるには大きさや position の位置からいちいち計算すれば出るのはわかるのですが、球体や物体同士が重なった場合の体積など複雑になった場合はどうやって計算すればよいかわからなかったので
<!DOCTYPE html>
<html>
<head>
<style>
body{
background:#000;
background-color:#000;
}
div#canvas-frame{
width: 512px;
height: 512px;
}
</style>
<meta charset="utf-8">
<title>shadow simulation</title>
<link href="../jquery-ui/jquery-ui.min.css" rel="stylesheet">
<link href="../jquery_jqplot_dist/jquery.jqplot.min.css" rel="stylesheet">
<link href="../css/laboratory_r2.css" rel="stylesheet">
<style>
/* 外部スタイルシートの読み込み */
</style>
<!-- 外部JavaScriptファイルの読み込み -->
<script type="text/javascript" src="../jquery-ui/external/jquery/jquery.js"></script>
<script type="text/javascript" src="../jquery-ui/jquery-ui.js"></script>
<script src="../three.min.js"></script>
<script src="../js/renderers/Projector.js"></script>
<script src="../js/renderers/CanvasRenderer.js"></script>
<script src="../js/controls/TrackballControls.js"></script>
<script src="../jquery_jqplot_dist/jquery.jqplot.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.canvasTextRenderer.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.logAxisRenderer.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.highlighter.min.js"></script>
<script src="../jquery_jqplot_dist/plugins/jqplot.cursor.min.js"></script>
<script type="text/javascript" src="../jqplotjs/plot2D_r5.js"></script>
////////////////////////////////////////////////////////////////////
// windowイベントの定義
////////////////////////////////////////////////////////////////////
//HTML文書読み込み完了後に実行するイベントの定義
//(すべてのHTML文書を読み込んでいなければ参照不能の要素があるため)
window.addEventListener("load", function () {
resizeTo(850, 610);
threeStart(); //Three.jsのスタート関数の実行
initEvent(); //イベントの準備
});
/////////////////////////////////////////////////////////////////////////
// 物理系の定義
///////////////////////////////////////////////////////////////////////////
//球クラスの定義
var CubeRotation = function (parameter) {
this.radius = parameter.radius; //半径
this.x = parameter.x; //x座標
this.y = parameter.y; //y座標
this.z = parameter.z; //z座標
};
//球オブジェクトの生成
var cube_rotation = new CubeRotation({ /*radius: 5,*/ x: 0, y: 0, z: 0});
////////////////////////////////////////////////////////////////////
// イベント準備関数
////////////////////////////////////////////////////////////////////
function initEvent() {
//タブ切り替えインターフェースの実装
$('#tabs').tabs({ selected: 0, /*fx: { opacity: 'toggle', duration: 100}*/ });
//スライダーインターフェースの実装
var strs = ['x', 'y', 'z'];
for (var i = 0; i < strs.length; i++) {
var axis = strs[i]; //軸の取得
var value = cube_rotation[axis]; //回転度
//座標表示用input要素に値を代入
document.getElementById("input_" + axis).value = value; //id名「input_○」の要素の「value」属性に値を代入
//input要素に値を入力した時のイベントを追加
document.getElementById("input_" + axis).addEventListener("change", function () {
//input要素に入力された値を取得する
var value = parseFloat(this.value) || 0;
//input要素に入力した値をcubeの回転度に代入する
var axis = this.id.replace("input_", ""); //id名から軸に変換(「input_○」→「○」)
cube_rotation[axis] = value;
});
}
}
////////////////////////////////////////////////////////////////////
// Three.jsスタート関数の定義
////////////////////////////////////////////////////////////////////
function threeStart() {
initThree(); //Three.js初期化関数の実行
initCamera(); //カメラ初期化関数の実行
initLight(); //光源初期化関数の実行
initObject(); //オブジェクト初期化関数の実行
loop(); //無限ループ関数の実行
}
////////////////////////////////////////////////////////////////////
// Three.js初期化関数の定義
////////////////////////////////////////////////////////////////////
//グローバル変数の宣言
var renderer, //レンダラーオブジェクト
scene, //シーンオブジェクト
canvasFrame; //キャンバスフレームのDOM要素
function initThree() {
//キャンバスフレームDOM要素の取得
canvasFrame = document.getElementById('canvas-frame');
//レンダラーオブジェクトの生成
renderer = new THREE.WebGLRenderer({ antialias: true });
if (!renderer) alert('Three.js の初期化に失敗しました');
//レンダラーのサイズの設定
renderer.setSize(canvasFrame.clientWidth, canvasFrame.clientHeight);
//キャンバスフレームDOM要素にcanvas要素を追加
canvasFrame.appendChild(renderer.domElement);
//レンダラークリアーカラーの設定
renderer.setClearColor(0xffffff, 1.0);
//シャドーマップの利用
renderer.shadowMapEnabled = true;
//シーンオブジェクトの生成
scene = new THREE.Scene();
}
////////////////////////////////////////////////////////////////////
// カメラ初期化関数の定義
////////////////////////////////////////////////////////////////////
//グローバル変数の宣言
var camera, //カメラオブジェクト
trackball; //トラックボールオブジェクト
function initCamera() {
//カメラオブジェクトの生成
camera = new THREE.PerspectiveCamera(45, canvasFrame.clientWidth / canvasFrame.clientHeight, 1, 10000);
//カメラの位置の設定
camera.position.set(300, 200, 200);
//カメラの上ベクトルの設定
camera.up.set(0, 0, 1);
//カメラの中心位置ベクトルの設定
camera.lookAt({ x: 0, y: 0, z: 100 }); //トラックボール利用時は自動的に無効
//トラックボールオブジェクトの宣言
trackball = new THREE.TrackballControls(camera, canvasFrame);
//トラックボール動作範囲のサイズとオフセットの設定
trackball.screen.width = canvasFrame.clientWidth; //横幅
trackball.screen.height = canvasFrame.clientHeight; //縦幅
trackball.screen.offsetLeft = canvasFrame.getBoundingClientRect().left; //左オフセット
trackball.screen.offsetTop = canvasFrame.getBoundingClientRect().top; //右オフセット
//トラックボールの回転無効化と回転速度の設定
trackball.noRotate = false;
trackball.rotateSpeed = 2.0;
//トラックボールの拡大無効化と拡大速度の設定
trackball.noZoom = false;
trackball.zoomSpeed = 1.0;
//トラックボールのカメラ中心移動の無効化と中心速度の設定
trackball.noPan = false;
trackball.panSpeed = 1.0;
trackball.target = new THREE.Vector3(0, 0, 10);
//トラックボールのスタティックムーブの有効化
trackball.staticMoving = true;
//トラックボールのダイナミックムーブ時の減衰定数
trackball.dynamicDampingFactor = 0.3;
}
////////////////////////////////////////////////////////////////////
// 光源初期化関数の定義
////////////////////////////////////////////////////////////////////
//グローバル変数の宣言
var directionalLight, //平行光源オブジェクト
ambientLight; //環境光オブジェクト
function initLight() {
//平行光源オブジェクトの生成
directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0);
//平行光源オブジェクトの位置の設定
directionalLight.position.set(0, 0, 800);
//平行光源オブジェクトの影の生成元
directionalLight.castShadow = true;
directionalLight.shadowDarkness = 1.0;
//directionalLight2 = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0);
//平行光源オブジェクトの位置の設定
//directionalLight2.position.set(300, 300, 300);
//平行光源オブジェクトのシーンへの追加
scene.add(directionalLight);
//平行光源オブジェクトのシャドウマップのサイズ
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
}
////////////////////////////////////////////////////////////////////
// オブジェクト初期化関数の定義
////////////////////////////////////////////////////////////////////
//グローバル変数の宣言
var cube; //球オブジェクト
var axis;
function initObject() {
axis = new THREE.AxisHelper(200);
scene.add(axis);
axis.position.set(0, 0, 0);
//自分で6面別々の色を指定する
var materials = [
new THREE.MeshLambertMaterial({color: 0xff0000}),
new THREE.MeshLambertMaterial({color: 0xff0000}),
new THREE.MeshLambertMaterial({color: 0x00ff00}),
new THREE.MeshLambertMaterial({color: 0x00ff00}),
new THREE.MeshLambertMaterial({color: 0x0000ff}),
new THREE.MeshLambertMaterial({color: 0x0000ff})
];
//形状オブジェクトの宣言と生成
var boxSize = 30;
var geometry = new THREE.BoxGeometry(boxSize, boxSize, boxSize);
var material = new THREE.MeshFaceMaterial(materials);
cube = new THREE.Mesh(geometry, material); //立方体オブジェクトの生成
cube.position.set(10, 10, 50);
cube.castShadow = true;
scene.add(cube); //立方体オブジェクトのシーンへの追加
var boxSize2 = 30;
var geometry2 = new THREE.BoxGeometry(boxSize2, boxSize2, boxSize2);
var material2 = new THREE.MeshLambertMaterial({color: 0x00ff00});
cube2 = new THREE.Mesh(geometry2, material2); //立方体オブジェクトの生成
cube2.position.set(0, 0, -150);
cube2.receiveShadow = true;
cube2.castShadow = true;
scene.add(cube2); //立方体オブジェクトのシーンへの追加
//床の描画
var plane_width = 1000;
var plane_geometry = new THREE.PlaneGeometry(plane_width, plane_width);
//材質オブジェクトの宣言
var plane_material = new THREE.MeshLambertMaterial({ color: 0x7fffd4, ambient: 0x050505 });
//平面オブジェクトの宣言と生成
var plane = new THREE.Mesh(plane_geometry, plane_material);
//平面オブジェクトの位置の設定
plane.position.set(0, 0, -500);
//平面オブジェクトに影を描画
plane.receiveShadow = true;
//平面オブジェクトのシーンへの追加
scene.add(plane);
}
////////////////////////////////////////////////////////////////////
// 無限ループ関数の定義
////////////////////////////////////////////////////////////////////
function loop() {
//トラックボールによるカメラオブジェクトのプロパティの更新
trackball.update();
//球オブジェクトの位置ベクトルを設定
cube.rotation.set(cube_rotation.x*Math.PI/180, cube_rotation.y*Math.PI/180, cube_rotation.z*Math.PI/180); //<------------------------------------------(変更2)
//クリアーカラーで初期化
renderer.clear();
//レンダリング
renderer.render(scene, camera);
//「loop()」関数の呼び出し
requestAnimationFrame(loop);
};
////////////////////////////////////////////////////
</script>
</head>
<body>
<!-- タブ切り替えインターフェース -->
<div id="tabs">
<!-- タブメニューリスト領域 -->
<ul id="tabList">
<li><a href="#tab1">cube simulation</a></li>
</ul>
<!-- タブコンテンツ領域1 -->
<div id="tab1" class="inner" style="background-color:0x000000;">
<div id="canvas-frame" style="background-color:0x000000;"></div>
<!-- コントローラー領域 -->
<div id="controller">
<h2>各種パラメーター</h2>
<h3>軸について</h3>
<table>
<tr>
<!-- x軸 -->
<td style="color:red;">x軸 (赤線)</td>
</tr>
<tr>
<!-- y軸 -->
<td style="color:green;">y軸 (緑線)</td>
</tr>
<tr>
<!-- z軸 -->
<td style="color:blue;">z軸 (青線)</td>
</tr>
</table>
<h3>deg</h3>
<table>
<tr>
<!-- x-->
<td>x</td>
<td><input type="text" value="" id="input_x" class="number"></td>
</tr>
<tr>
<!-- y -->
<td>y</td>
<td><input type="text" value="" id="input_y" class="number"></td>
</tr>
<tr>
<!-- z -->
<td>z</td>
<td><input type="text" value="" id="input_z" class="number"></td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>