Skip to content
Open
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dwsync.xml
intermediate
publish
.idea
bower_components

# build script local files
build/buildinfo.properties
Expand Down
81 changes: 55 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
The aim of this project is to create a fully featured search tree for the [THREE.js WebGL library](http://mrdoob.github.com/three.js/).

```html
This build is stable up to THREE.js ~r60
This build is stable up to THREE.js ~r78
(updates to latest THREE build on hold as my time is required on other projects)
```

Expand All @@ -23,26 +23,40 @@ This build is stable up to THREE.js ~r60
* rebuild ( account for moving objects, trade-off is performance and is not recommended )
* search by position and radius ( i.e. sphere search )
* search by ray using position, direction, and distance/far ( does not include specific collisions, only potential )
* raycast search results using built in THREE.Raycaster additions ( does not modify the Raycaster except to add new functions )
* raycast search results using built in `THREE.Raycaster` additions ( does not modify the Raycaster except to add new functions )

## Needs

* reworking / optimization of insert and removal ( currently we have to force a transform update in case the object is added before first three update )

## Migration
## Migration

#### r60 → r78
- Removed extending `THREE.RayCaster` with custom methods
- Added `raycast` method on `THREE.Octree`
- Added `raycast` method on `THREE.OctreeObjectData`
- Removed `THREE.Face4` support and its corresponding methods (`THREE.Face4` was deprecated in r60)
- Removed exchanging of faces array on geometry while intersecting `THREE.Octree`
- Removed getting radius from `object.boundRadius` (was replaced in r66(?) by `object.geometry.boundingSphere.radius`)
- Renamed `this.vertices` inside `THREE.OctreeObjectData` to `this.vertex` (it holds an instance of `THREE.Vector3`)
- Renamed `this.faces` inside `THREE.OctreeObjectData` to `this.face` (it holds an instance of `THREE.Face3`)
- Renamed `getFace3BoundingRadius` back to previous `getFaceBoundingRadius` (since `THREE.Face4` support is removed)
- Changed code formatting @mrdoob style (https://zz85.github.io/mrdoobapproves/)

#### r56 → r60
- Octree can now handle vertices (and particle systems)
- `add` method now takes a options object as the second parameter, which may contain booleans for `useFaces` and `useVertices`
- `OctreeObjectData.usesFaces` removed, use `.faces`, `.face3`, or `.face4`
- `OctreeObjectData.getFaceBoundingRadius` split into `.getFace3BoundingRadius` and `getFace4BoundingRadius`
- `OctreeObjectData.vertices` added
- `OctreeObjectData.vertices` added

#### r51 → r56
- Function naming conventions from `hello_world()` to THREE style `helloWorld()`
- Script renamed from `ThreeOctree.js` to `threeoctree.js`
- `Ray.intersectOctreeObjects/intersectOctreeObject` to `Raycaster.intersectOctreeObjects/intersectOctreeObject`
- `Vector3/Matrix4` functions from THREE r51 to r56 ( see: https://github.com/mrdoob/three.js/wiki/Migration )

## Usage
## Installation

Download the [minified script](https://github.com/collinhover/threeoctree/blob/master/threeoctree.min.js) and include it in your html after the [THREE.js WebGL library](http://mrdoob.github.com/three.js/).

Expand All @@ -51,6 +65,21 @@ Download the [minified script](https://github.com/collinhover/threeoctree/blob/m
<script src="js/threeoctree.min.js"></script>
```

You can also use bower for installing. Add the following line to the dependencies inside your `bower.json` file:
```json
"dependencies": {
...
"threeoctree": "https://github.com/collinhover/threeoctree"
...
}
```
In case you want to use this library with a different version then the shipped three.js r78 or when you have conflicts when running `bower update` with the `three.js` version you can surpress this by adding the three.js library/dependency of your choice inside the resolutions key as follows:
```json
"resolutions": {
"three.js": "r77"
}
```

#### Initialize

```html
Expand Down Expand Up @@ -136,40 +165,40 @@ octree.search( ray.origin, ray.far, true, ray.direction );

#### Intersections

This octree adds two functions to the THREE.Raycaster class to help use the search results: .intersectOctreeObjects(), and .intersectOctreeObject(). In most cases you will use only the former:
An octree can be passed to the raycaster immediately as you do with normal intersecting:

```html
var octreeResults = octree.search( rayCaster.ray.origin, rayCaster.ray.far, true, rayCaster.ray.direction )
var intersections = rayCaster.intersectOctreeObjects( octreeResults );
// octree is an instance of `THREE.Octree`
var objects = rayCaster.intersectObject( octree )
```

If you want to intersect an array of octree results you can pass them also as normally:

```html
// octreeResults is an array of `THREE.OctreeObjectData`
var objects = rayCaster.intersectObjects( octreeResults )
```

If you wish to get an intersection from a user's mouse click, this is easy enough:

```html

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();

function onClick ( event ) {

// record mouse x/y position as a 3D vector

var mousePosition = new THREE.Vector3();
mousePosition.x = ( event.pageX / window.innerWidth ) * 2 - 1;
mousePosition.y = -( event.pageY / window.innerHeight ) * 2 + 1;
mousePosition.z = 0.5;
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components

// use THREE.Projector to unproject mouse position into scene via camera
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

var projector = new THREE.Projector();
projector.unprojectVector( mousePosition, camera );

// create new ray caster
// origin is camera position
// direction is unprojected mouse position - camera position
raycaster.setFromCamera( mouse, camera );

var origin = new THREE.Vector3().copy( camera.position );
var direction = new THREE.Vector3().copy( mousePosition.sub( camera.position ) ).normalize();
var rayCaster = new THREE.Raycaster( origin, direction );

// now search octree and find intersections using method above
// now search octree by passing it to the rayCaster as mentioned above
...
var intersects = raycaster.intersectObjects( scene.children );

}
```
Expand Down
16 changes: 16 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "threeoctree.js",
"version": "0.9",
"authors": [
],
"dependencies": {
"three.js": "https://github.com/mrdoob/three.js.git#r78"
},
"ignore": [
"examples",
"test",
"bower_components",
"README.md",
".gitignore"
]
}
78 changes: 78 additions & 0 deletions examples/js/Detector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @author alteredq / http://alteredqualia.com/
* @author mr.doob / http://mrdoob.com/
*/

var Detector = {

canvas: !! window.CanvasRenderingContext2D,
webgl: ( function () {

try {

var canvas = document.createElement( 'canvas' ); return !! ( window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ) );

} catch ( e ) {

return false;

}

} )(),
workers: !! window.Worker,
fileapi: window.File && window.FileReader && window.FileList && window.Blob,

getWebGLErrorMessage: function () {

var element = document.createElement( 'div' );
element.id = 'webgl-error-message';
element.style.fontFamily = 'monospace';
element.style.fontSize = '13px';
element.style.fontWeight = 'normal';
element.style.textAlign = 'center';
element.style.background = '#fff';
element.style.color = '#000';
element.style.padding = '1.5em';
element.style.width = '400px';
element.style.margin = '5em auto 0';

if ( ! this.webgl ) {

element.innerHTML = window.WebGLRenderingContext ? [
'Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />',
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
].join( '\n' ) : [
'Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>',
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
].join( '\n' );

}

return element;

},

addGetWebGLMessage: function ( parameters ) {

var parent, id, element;

parameters = parameters || {};

parent = parameters.parent !== undefined ? parameters.parent : document.body;
id = parameters.id !== undefined ? parameters.id : 'oldie';

element = Detector.getWebGLErrorMessage();
element.id = id;

parent.appendChild( element );

}

};

// browserify support
if ( typeof module === 'object' ) {

module.exports = Detector;

}
Loading