test
81
Dockerfile
@@ -1,24 +1,23 @@
|
||||
# ===== 基础镜像阶段 =====
|
||||
# 使用预装字体的OpenJDK镜像,避免重复安装
|
||||
FROM openjdk:8-jdk AS base
|
||||
# 使用更小的Alpine OpenJRE镜像
|
||||
FROM openjdk:8-jre-alpine AS base
|
||||
|
||||
# 设置维护者信息
|
||||
LABEL maintainer="digital-archive-team"
|
||||
|
||||
# 使用阿里云镜像源并安装基础包
|
||||
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
||||
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y \
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
curl \
|
||||
bash \
|
||||
&& apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
ttf-dejavu \
|
||||
fontconfig \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# ===== Maven 构建阶段 =====
|
||||
# 使用Maven镜像进行构建
|
||||
FROM maven:3.8.4-openjdk-8 AS builder
|
||||
# 使用更小的Alpine Maven镜像进行构建
|
||||
FROM maven:3.8.4-openjdk-8-alpine AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /build
|
||||
@@ -33,7 +32,7 @@ RUN mkdir -p /root/.m2/repository
|
||||
# 复制本地lib目录中的JAR文件
|
||||
COPY src/main/lib/ /tmp/local-jars/
|
||||
|
||||
# 手动安装本地JAR到Maven仓库
|
||||
# 手动安装本地JAR到Maven仓库(只安装实际使用的)
|
||||
RUN mvn install:install-file \
|
||||
-Dfile=/tmp/local-jars/aspose-cells-8.5.2.jar \
|
||||
-DgroupId=com.aspose \
|
||||
@@ -59,7 +58,7 @@ RUN mvn install:install-file \
|
||||
-B -s /root/.m2/settings.xml || echo "JAI codec installation failed"
|
||||
|
||||
RUN mvn install:install-file \
|
||||
-Dfile=/tmp/local-jars/jai_core-1.1.3.jar \
|
||||
-Dfile=/tmp/local-jars/jai_core.jar \
|
||||
-DgroupId=javax.media \
|
||||
-DartifactId=jai_core \
|
||||
-Dversion=1.1.3 \
|
||||
@@ -67,20 +66,20 @@ RUN mvn install:install-file \
|
||||
-B -s /root/.m2/settings.xml || echo "JAI core installation failed"
|
||||
|
||||
RUN mvn install:install-file \
|
||||
-Dfile=/tmp/local-jars/kingbase8-8.6.0.jar \
|
||||
-DgroupId=com.kingbase8 \
|
||||
-DartifactId=kingbase8 \
|
||||
-Dversion=8.6.0 \
|
||||
-Dfile=/tmp/local-jars/jce-0.0.1.jar \
|
||||
-DgroupId=org.bouncycastle \
|
||||
-DartifactId=jce \
|
||||
-Dversion=0.0.1 \
|
||||
-Dpackaging=jar \
|
||||
-B -s /root/.m2/settings.xml || echo "Kingbase driver installation failed"
|
||||
-B -s /root/.m2/settings.xml || echo "JCE installation failed"
|
||||
|
||||
RUN mvn install:install-file \
|
||||
-Dfile=/tmp/local-jars/twain4java-0.3.3-all.jar \
|
||||
-DgroupId=twain4java \
|
||||
-DartifactId=twain4java \
|
||||
-Dversion=0.3.3 \
|
||||
-Dfile=/tmp/local-jars/agent-1.0.0.jar \
|
||||
-DgroupId=com.yh \
|
||||
-DartifactId=scofd \
|
||||
-Dversion=1.0.0 \
|
||||
-Dpackaging=jar \
|
||||
-B -s /root/.m2/settings.xml || echo "TWAIN installation failed"
|
||||
-B -s /root/.m2/settings.xml || echo "Agent installation failed"
|
||||
|
||||
# 设置Maven仓库权限
|
||||
RUN chown -R root:root /root/.m2
|
||||
@@ -88,10 +87,13 @@ RUN chown -R root:root /root/.m2
|
||||
# 复制源代码
|
||||
COPY src ./src
|
||||
|
||||
# 构建应用
|
||||
RUN mvn clean package -DskipTests -B -s /root/.m2/settings.xml -e
|
||||
# 构建应用(优化构建参数)
|
||||
RUN mvn clean package -DskipTests -B -s /root/.m2/settings.xml -e \
|
||||
-o \
|
||||
-Dmaven.test.skip=true \
|
||||
-Dmaven.compiler.optimize=true
|
||||
|
||||
# 检查构建结果
|
||||
# 检查构建结果并复制正确的JAR文件
|
||||
RUN echo "=== 检查构建结果 ===" && \
|
||||
ls -la /build/target/ && \
|
||||
echo "=== 查找所有 JAR 文件 ===" && \
|
||||
@@ -106,34 +108,19 @@ RUN echo "=== 检查构建结果 ===" && \
|
||||
FROM base
|
||||
|
||||
# 设置环境变量
|
||||
ENV JAVA_OPTS="-Xmx2g -Xms1g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Djava.awt.headless=true"
|
||||
ENV JAVA_OPTS="-Xmx1g -Xms512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Djava.awt.headless=true -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
|
||||
ENV SPRING_PROFILES_ACTIVE=prod
|
||||
|
||||
# 创建应用用户和目录(兼容 Debian/Ubuntu 与 Alpine/busybox 工具集)
|
||||
RUN set -eux; \
|
||||
if command -v groupadd >/dev/null 2>&1; then \
|
||||
# Debian/Ubuntu/一般 GNU 工具链
|
||||
groupadd -g 1001 app; \
|
||||
useradd -u 1001 -g app -s /bin/sh -d /app -M app; \
|
||||
elif command -v addgroup >/dev/null 2>&1; then \
|
||||
# adduser/addgroup 工具链:区分 --gid 可用与否
|
||||
if addgroup --help 2>&1 | grep -q -- '--gid'; then \
|
||||
addgroup --gid 1001 app; \
|
||||
adduser --disabled-password --shell /bin/sh --uid 1001 --ingroup app app; \
|
||||
else \
|
||||
addgroup -g 1001 app; \
|
||||
adduser -D -s /bin/sh -u 1001 -G app app; \
|
||||
fi; \
|
||||
else \
|
||||
echo 'no user/group management tools found' >&2; exit 1; \
|
||||
fi; \
|
||||
# 创建应用用户和目录
|
||||
RUN addgroup -g 1001 app && \
|
||||
adduser -D -s /bin/sh -u 1001 -G app app && \
|
||||
mkdir -p /app/data/upload \
|
||||
/app/data/temp \
|
||||
/app/data/unzip \
|
||||
/app/data/images \
|
||||
/app/data/reports \
|
||||
/app/data/elasticsearch \
|
||||
/app/logs; \
|
||||
/app/logs && \
|
||||
chown -R app:app /app
|
||||
|
||||
# 设置工作目录
|
||||
@@ -158,5 +145,5 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
# 暴露端口
|
||||
EXPOSE 9081
|
||||
|
||||
# 启动应用(不使用tini,直接启动)
|
||||
CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
||||
# 启动应用
|
||||
CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
|
||||
14
doc/1.md
@@ -226,19 +226,7 @@ PRIMARY KEY (`accept_uuid`)
|
||||
|
||||
|
||||
##1、查询在销品牌
|
||||
select
|
||||
product_uuid,
|
||||
product_code,
|
||||
product_name,
|
||||
factory_simple_name,
|
||||
brand_name,
|
||||
is_abnormity,
|
||||
length,
|
||||
width,
|
||||
height,
|
||||
tar_qty,
|
||||
bar_code,
|
||||
package_qty,
|
||||
|
||||
bar_code2,
|
||||
package_qty2,
|
||||
bar_code3,
|
||||
|
||||
@@ -16,8 +16,27 @@ public class CityBusinessSystemIntegration {
|
||||
|
||||
// 获取数据库连接
|
||||
private static Connection getConnection() throws Exception {
|
||||
Class.forName(driver);
|
||||
return DriverManager.getConnection(url, user, password);
|
||||
try {
|
||||
LOGGER.log(Level.INFO, "正在连接数据库: " + url);
|
||||
LOGGER.log(Level.INFO, "使用用户: " + user);
|
||||
LOGGER.log(Level.INFO, "加载驱动: " + driver);
|
||||
|
||||
Class.forName(driver);
|
||||
LOGGER.log(Level.INFO, "驱动加载成功,开始建立连接...");
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
Connection conn = DriverManager.getConnection(url, user, password);
|
||||
long endTime = System.currentTimeMillis();
|
||||
|
||||
LOGGER.log(Level.INFO, "数据库连接成功,耗时: " + (endTime - startTime) + "ms");
|
||||
return conn;
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOGGER.log(Level.SEVERE, "数据库驱动未找到: " + driver, e);
|
||||
throw e;
|
||||
} catch (SQLException e) {
|
||||
LOGGER.log(Level.SEVERE, "数据库连接失败. URL: " + url + ", User: " + user + ", SQLState: " + e.getSQLState() + ", ErrorCode: " + e.getErrorCode(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// 查询
|
||||
|
||||
@@ -97,7 +97,7 @@ ycj:
|
||||
# 市公司业务数据系统集成配置
|
||||
cityBusiness:
|
||||
driverClassName: com.mysql.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/city_business?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
|
||||
url: jdbc:mysql://localhost:3306/citybusiness?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&connectTimeout=5000&socketTimeout=5000
|
||||
username: root
|
||||
password: Abc@123456
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 412 B |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 112 B |
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 486 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 110 B |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 332 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 93 B |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 354 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 201 B |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 453 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 960 B |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 70 B |
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*
|
||||
* Full-screen textured quad shader
|
||||
*/
|
||||
|
||||
THREE.CopyShader = {
|
||||
|
||||
uniforms: {
|
||||
|
||||
"tDiffuse": { value: null },
|
||||
"opacity": { value: 1.0 }
|
||||
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
"vUv = uv;",
|
||||
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
"uniform float opacity;",
|
||||
|
||||
"uniform sampler2D tDiffuse;",
|
||||
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
"vec4 texel = texture2D( tDiffuse, vUv );",
|
||||
"gl_FragColor = opacity * texel;",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" )
|
||||
|
||||
};
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* @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;
|
||||
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* @author zz85 / https://github.com/zz85
|
||||
* @author mrdoob / http://mrdoob.com
|
||||
* Running this will allow you to drag three.js objects around the screen.
|
||||
*/
|
||||
|
||||
THREE.DragControls = function ( _objects, _camera, _domElement ) {
|
||||
|
||||
if ( _objects instanceof THREE.Camera ) {
|
||||
|
||||
console.warn( 'THREE.DragControls: Constructor now expects ( objects, camera, domElement )' );
|
||||
var temp = _objects; _objects = _camera; _camera = temp;
|
||||
|
||||
}
|
||||
|
||||
var _plane = new THREE.Plane();
|
||||
var _raycaster = new THREE.Raycaster();
|
||||
|
||||
var _mouse = new THREE.Vector2();
|
||||
var _offset = new THREE.Vector3();
|
||||
var _intersection = new THREE.Vector3();
|
||||
|
||||
var _selected = null, _hovered = null;
|
||||
|
||||
//
|
||||
|
||||
var scope = this;
|
||||
|
||||
function activate() {
|
||||
|
||||
_domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||
_domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
|
||||
_domElement.addEventListener( 'mouseup', onDocumentMouseCancel, false );
|
||||
_domElement.addEventListener( 'mouseleave', onDocumentMouseCancel, false );
|
||||
_domElement.addEventListener( 'touchmove', onDocumentTouchMove, false );
|
||||
_domElement.addEventListener( 'touchstart', onDocumentTouchStart, false );
|
||||
_domElement.addEventListener( 'touchend', onDocumentTouchEnd, false );
|
||||
|
||||
}
|
||||
|
||||
function deactivate() {
|
||||
|
||||
_domElement.removeEventListener( 'mousemove', onDocumentMouseMove, false );
|
||||
_domElement.removeEventListener( 'mousedown', onDocumentMouseDown, false );
|
||||
_domElement.removeEventListener( 'mouseup', onDocumentMouseCancel, false );
|
||||
_domElement.removeEventListener( 'mouseleave', onDocumentMouseCancel, false );
|
||||
_domElement.removeEventListener( 'touchmove', onDocumentTouchMove, false );
|
||||
_domElement.removeEventListener( 'touchstart', onDocumentTouchStart, false );
|
||||
_domElement.removeEventListener( 'touchend', onDocumentTouchEnd, false );
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
deactivate();
|
||||
|
||||
}
|
||||
|
||||
function onDocumentMouseMove( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var rect = _domElement.getBoundingClientRect();
|
||||
|
||||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
|
||||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
|
||||
|
||||
_raycaster.setFromCamera( _mouse, _camera );
|
||||
|
||||
if ( _selected && scope.enabled ) {
|
||||
|
||||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
_selected.position.copy( _intersection.sub( _offset ) );
|
||||
|
||||
}
|
||||
|
||||
scope.dispatchEvent( { type: 'drag', object: _selected } );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
_raycaster.setFromCamera( _mouse, _camera );
|
||||
|
||||
var intersects = _raycaster.intersectObjects( _objects );
|
||||
|
||||
if ( intersects.length > 0 ) {
|
||||
|
||||
var object = intersects[ 0 ].object;
|
||||
|
||||
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), object.position );
|
||||
|
||||
if ( _hovered !== object ) {
|
||||
|
||||
scope.dispatchEvent( { type: 'hoveron', object: object } );
|
||||
|
||||
_domElement.style.cursor = 'pointer';
|
||||
_hovered = object;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( _hovered !== null ) {
|
||||
|
||||
scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
||||
|
||||
_domElement.style.cursor = 'auto';
|
||||
_hovered = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onDocumentMouseDown( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
_raycaster.setFromCamera( _mouse, _camera );
|
||||
|
||||
var intersects = _raycaster.intersectObjects( _objects );
|
||||
|
||||
if ( intersects.length > 0 ) {
|
||||
|
||||
_selected = intersects[ 0 ].object;
|
||||
|
||||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
_offset.copy( _intersection ).sub( _selected.position );
|
||||
|
||||
}
|
||||
|
||||
_domElement.style.cursor = 'move';
|
||||
|
||||
scope.dispatchEvent( { type: 'dragstart', object: _selected } );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function onDocumentMouseCancel( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( _selected ) {
|
||||
|
||||
scope.dispatchEvent( { type: 'dragend', object: _selected } );
|
||||
|
||||
_selected = null;
|
||||
|
||||
}
|
||||
|
||||
_domElement.style.cursor = 'auto';
|
||||
|
||||
}
|
||||
|
||||
function onDocumentTouchMove( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
event = event.changedTouches[ 0 ];
|
||||
|
||||
var rect = _domElement.getBoundingClientRect();
|
||||
|
||||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
|
||||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
|
||||
|
||||
_raycaster.setFromCamera( _mouse, _camera );
|
||||
|
||||
if ( _selected && scope.enabled ) {
|
||||
|
||||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
_selected.position.copy( _intersection.sub( _offset ) );
|
||||
|
||||
}
|
||||
|
||||
scope.dispatchEvent( { type: 'drag', object: _selected } );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onDocumentTouchStart( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
event = event.changedTouches[ 0 ];
|
||||
|
||||
var rect = _domElement.getBoundingClientRect();
|
||||
|
||||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
|
||||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
|
||||
|
||||
_raycaster.setFromCamera( _mouse, _camera );
|
||||
|
||||
var intersects = _raycaster.intersectObjects( _objects );
|
||||
|
||||
if ( intersects.length > 0 ) {
|
||||
|
||||
_selected = intersects[ 0 ].object;
|
||||
|
||||
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _selected.position );
|
||||
|
||||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
_offset.copy( _intersection ).sub( _selected.position );
|
||||
|
||||
}
|
||||
|
||||
_domElement.style.cursor = 'move';
|
||||
|
||||
scope.dispatchEvent( { type: 'dragstart', object: _selected } );
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function onDocumentTouchEnd( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ( _selected ) {
|
||||
|
||||
scope.dispatchEvent( { type: 'dragend', object: _selected } );
|
||||
|
||||
_selected = null;
|
||||
|
||||
}
|
||||
|
||||
_domElement.style.cursor = 'auto';
|
||||
|
||||
}
|
||||
|
||||
activate();
|
||||
|
||||
// API
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
this.activate = activate;
|
||||
this.deactivate = deactivate;
|
||||
this.dispose = dispose;
|
||||
|
||||
// Backward compatibility
|
||||
|
||||
this.setObjects = function () {
|
||||
|
||||
console.error( 'THREE.DragControls: setObjects() has been removed.' );
|
||||
|
||||
};
|
||||
|
||||
this.on = function ( type, listener ) {
|
||||
|
||||
console.warn( 'THREE.DragControls: on() has been deprecated. Use addEventListener() instead.' );
|
||||
scope.addEventListener( type, listener );
|
||||
|
||||
};
|
||||
|
||||
this.off = function ( type, listener ) {
|
||||
|
||||
console.warn( 'THREE.DragControls: off() has been deprecated. Use removeEventListener() instead.' );
|
||||
scope.removeEventListener( type, listener );
|
||||
|
||||
};
|
||||
|
||||
this.notify = function ( type ) {
|
||||
|
||||
console.error( 'THREE.DragControls: notify() has been deprecated. Use dispatchEvent() instead.' );
|
||||
scope.dispatchEvent( { type: type } );
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
THREE.DragControls.prototype = Object.create( THREE.EventDispatcher.prototype );
|
||||
THREE.DragControls.prototype.constructor = THREE.DragControls;
|
||||
@@ -1,189 +0,0 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.EffectComposer = function ( renderer, renderTarget ) {
|
||||
|
||||
this.renderer = renderer;
|
||||
|
||||
if ( renderTarget === undefined ) {
|
||||
|
||||
var parameters = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
format: THREE.RGBAFormat,
|
||||
stencilBuffer: false
|
||||
};
|
||||
|
||||
var size = renderer.getDrawingBufferSize();
|
||||
renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters );
|
||||
renderTarget.texture.name = 'EffectComposer.rt1';
|
||||
|
||||
}
|
||||
|
||||
this.renderTarget1 = renderTarget;
|
||||
this.renderTarget2 = renderTarget.clone();
|
||||
this.renderTarget2.texture.name = 'EffectComposer.rt2';
|
||||
|
||||
this.writeBuffer = this.renderTarget1;
|
||||
this.readBuffer = this.renderTarget2;
|
||||
|
||||
this.passes = [];
|
||||
|
||||
// dependencies
|
||||
|
||||
if ( THREE.CopyShader === undefined ) {
|
||||
|
||||
console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );
|
||||
|
||||
}
|
||||
|
||||
if ( THREE.ShaderPass === undefined ) {
|
||||
|
||||
console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );
|
||||
|
||||
}
|
||||
|
||||
this.copyPass = new THREE.ShaderPass( THREE.CopyShader );
|
||||
|
||||
};
|
||||
|
||||
Object.assign( THREE.EffectComposer.prototype, {
|
||||
|
||||
swapBuffers: function () {
|
||||
|
||||
var tmp = this.readBuffer;
|
||||
this.readBuffer = this.writeBuffer;
|
||||
this.writeBuffer = tmp;
|
||||
|
||||
},
|
||||
|
||||
addPass: function ( pass ) {
|
||||
|
||||
this.passes.push( pass );
|
||||
|
||||
var size = this.renderer.getDrawingBufferSize();
|
||||
pass.setSize( size.width, size.height );
|
||||
|
||||
},
|
||||
|
||||
insertPass: function ( pass, index ) {
|
||||
|
||||
this.passes.splice( index, 0, pass );
|
||||
|
||||
},
|
||||
|
||||
render: function ( delta ) {
|
||||
|
||||
var maskActive = false;
|
||||
|
||||
var pass, i, il = this.passes.length;
|
||||
|
||||
for ( i = 0; i < il; i ++ ) {
|
||||
|
||||
pass = this.passes[ i ];
|
||||
|
||||
if ( pass.enabled === false ) continue;
|
||||
|
||||
pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );
|
||||
|
||||
if ( pass.needsSwap ) {
|
||||
|
||||
if ( maskActive ) {
|
||||
|
||||
var context = this.renderer.context;
|
||||
|
||||
context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
|
||||
|
||||
this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );
|
||||
|
||||
context.stencilFunc( context.EQUAL, 1, 0xffffffff );
|
||||
|
||||
}
|
||||
|
||||
this.swapBuffers();
|
||||
|
||||
}
|
||||
|
||||
if ( THREE.MaskPass !== undefined ) {
|
||||
|
||||
if ( pass instanceof THREE.MaskPass ) {
|
||||
|
||||
maskActive = true;
|
||||
|
||||
} else if ( pass instanceof THREE.ClearMaskPass ) {
|
||||
|
||||
maskActive = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
reset: function ( renderTarget ) {
|
||||
|
||||
if ( renderTarget === undefined ) {
|
||||
|
||||
var size = this.renderer.getDrawingBufferSize();
|
||||
|
||||
renderTarget = this.renderTarget1.clone();
|
||||
renderTarget.setSize( size.width, size.height );
|
||||
|
||||
}
|
||||
|
||||
this.renderTarget1.dispose();
|
||||
this.renderTarget2.dispose();
|
||||
this.renderTarget1 = renderTarget;
|
||||
this.renderTarget2 = renderTarget.clone();
|
||||
|
||||
this.writeBuffer = this.renderTarget1;
|
||||
this.readBuffer = this.renderTarget2;
|
||||
|
||||
},
|
||||
|
||||
setSize: function ( width, height ) {
|
||||
|
||||
this.renderTarget1.setSize( width, height );
|
||||
this.renderTarget2.setSize( width, height );
|
||||
|
||||
for ( var i = 0; i < this.passes.length; i ++ ) {
|
||||
|
||||
this.passes[ i ].setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
THREE.Pass = function () {
|
||||
|
||||
// if set to true, the pass is processed by the composer
|
||||
this.enabled = true;
|
||||
|
||||
// if set to true, the pass indicates to swap read and write buffer after rendering
|
||||
this.needsSwap = true;
|
||||
|
||||
// if set to true, the pass clears its buffer before rendering
|
||||
this.clear = false;
|
||||
|
||||
// if set to true, the result of the pass is rendered to screen
|
||||
this.renderToScreen = false;
|
||||
|
||||
};
|
||||
|
||||
Object.assign( THREE.Pass.prototype, {
|
||||
|
||||
setSize: function ( width, height ) {},
|
||||
|
||||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
||||
|
||||
console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
@@ -1,561 +0,0 @@
|
||||
/**
|
||||
* Loads a Wavefront .mtl file specifying materials
|
||||
*
|
||||
* @author angelxuanchang
|
||||
*/
|
||||
|
||||
THREE.MTLLoader = function ( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
};
|
||||
|
||||
THREE.MTLLoader.prototype = {
|
||||
|
||||
constructor: THREE.MTLLoader,
|
||||
|
||||
/**
|
||||
* Loads and parses a MTL asset from a URL.
|
||||
*
|
||||
* @param {String} url - URL to the MTL file.
|
||||
* @param {Function} [onLoad] - Callback invoked with the loaded object.
|
||||
* @param {Function} [onProgress] - Callback for download progress.
|
||||
* @param {Function} [onError] - Callback for download errors.
|
||||
*
|
||||
* @see setPath setTexturePath
|
||||
*
|
||||
* @note In order for relative texture references to resolve correctly
|
||||
* you must call setPath and/or setTexturePath explicitly prior to load.
|
||||
*/
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( this.manager );
|
||||
loader.setPath( this.path );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set base path for resolving references.
|
||||
* If set this path will be prepended to each loaded and found reference.
|
||||
*
|
||||
* @see setTexturePath
|
||||
* @param {String} path
|
||||
* @return {THREE.MTLLoader}
|
||||
*
|
||||
* @example
|
||||
* mtlLoader.setPath( 'assets/obj/' );
|
||||
* mtlLoader.load( 'my.mtl', ... );
|
||||
*/
|
||||
setPath: function ( path ) {
|
||||
|
||||
this.path = path;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Set base path for resolving texture references.
|
||||
* If set this path will be prepended found texture reference.
|
||||
* If not set and setPath is, it will be used as texture base path.
|
||||
*
|
||||
* @see setPath
|
||||
* @param {String} path
|
||||
* @return {THREE.MTLLoader}
|
||||
*
|
||||
* @example
|
||||
* mtlLoader.setPath( 'assets/obj/' );
|
||||
* mtlLoader.setTexturePath( 'assets/textures/' );
|
||||
* mtlLoader.load( 'my.mtl', ... );
|
||||
*/
|
||||
setTexturePath: function ( path ) {
|
||||
|
||||
this.texturePath = path;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setBaseUrl: function ( path ) {
|
||||
|
||||
console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' );
|
||||
|
||||
return this.setTexturePath( path );
|
||||
|
||||
},
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setMaterialOptions: function ( value ) {
|
||||
|
||||
this.materialOptions = value;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a MTL file.
|
||||
*
|
||||
* @param {String} text - Content of MTL file
|
||||
* @return {THREE.MTLLoader.MaterialCreator}
|
||||
*
|
||||
* @see setPath setTexturePath
|
||||
*
|
||||
* @note In order for relative texture references to resolve correctly
|
||||
* you must call setPath and/or setTexturePath explicitly prior to parse.
|
||||
*/
|
||||
parse: function ( text ) {
|
||||
// 换行作为分界点分割字符串
|
||||
var lines = text.split( '\n' );
|
||||
var info = {};
|
||||
// \s 匹配任何空白字符,包括空格、制表符、换页符等等
|
||||
var delimiter_pattern = /\s+/;
|
||||
var materialsInfo = {};
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
var line = lines[ i ];
|
||||
// .trim():删除字符串两端的空白字符。
|
||||
line = line.trim();
|
||||
|
||||
if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
|
||||
|
||||
// Blank line or comment ignore
|
||||
continue;
|
||||
|
||||
}
|
||||
// 返回空格首次出现的位置
|
||||
var pos = line.indexOf( ' ' );
|
||||
// 提取mtl文件属性
|
||||
var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
|
||||
key = key.toLowerCase();
|
||||
// 提取mtl文件属性对应值的字符串
|
||||
var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : '';
|
||||
value = value.trim();
|
||||
|
||||
if ( key === 'newmtl' ) {
|
||||
|
||||
// New material
|
||||
|
||||
info = { name: value };
|
||||
materialsInfo[ value ] = info;
|
||||
|
||||
} else if ( info ) {
|
||||
|
||||
if ( key === 'ka' || key === 'kd' || key === 'ks' ) {
|
||||
// 分割属性值对应的字符串
|
||||
var ss = value.split( delimiter_pattern, 3 );
|
||||
info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
|
||||
|
||||
} else {
|
||||
|
||||
info[ key ] = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions );
|
||||
materialCreator.setCrossOrigin( this.crossOrigin );
|
||||
materialCreator.setManager( this.manager );
|
||||
materialCreator.setMaterials( materialsInfo );
|
||||
return materialCreator;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new THREE-MTLLoader.MaterialCreator
|
||||
* @param baseUrl - Url relative to which textures are loaded
|
||||
* @param options - Set of options on how to construct the materials
|
||||
* side: Which side to apply the material
|
||||
* THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
|
||||
* wrap: What type of wrapping to apply for textures
|
||||
* THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
|
||||
* normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
|
||||
* Default: false, assumed to be already normalized
|
||||
* ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
|
||||
* Default: false
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) {
|
||||
|
||||
this.baseUrl = baseUrl || '';
|
||||
this.options = options;
|
||||
this.materialsInfo = {};
|
||||
this.materials = {};
|
||||
this.materialsArray = [];
|
||||
this.nameLookup = {};
|
||||
|
||||
this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
|
||||
this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
|
||||
|
||||
};
|
||||
|
||||
THREE.MTLLoader.MaterialCreator.prototype = {
|
||||
|
||||
constructor: THREE.MTLLoader.MaterialCreator,
|
||||
|
||||
crossOrigin: 'Anonymous',
|
||||
|
||||
setCrossOrigin: function ( value ) {
|
||||
|
||||
this.crossOrigin = value;
|
||||
|
||||
},
|
||||
|
||||
setManager: function ( value ) {
|
||||
|
||||
this.manager = value;
|
||||
|
||||
},
|
||||
|
||||
setMaterials: function ( materialsInfo ) {
|
||||
|
||||
this.materialsInfo = this.convert( materialsInfo );
|
||||
this.materials = {};
|
||||
this.materialsArray = [];
|
||||
this.nameLookup = {};
|
||||
|
||||
},
|
||||
|
||||
convert: function ( materialsInfo ) {
|
||||
|
||||
if ( ! this.options ) return materialsInfo;
|
||||
|
||||
var converted = {};
|
||||
|
||||
for ( var mn in materialsInfo ) {
|
||||
|
||||
// Convert materials info into normalized form based on options
|
||||
|
||||
var mat = materialsInfo[ mn ];
|
||||
|
||||
var covmat = {};
|
||||
|
||||
converted[ mn ] = covmat;
|
||||
|
||||
for ( var prop in mat ) {
|
||||
|
||||
var save = true;
|
||||
var value = mat[ prop ];
|
||||
var lprop = prop.toLowerCase();
|
||||
|
||||
switch ( lprop ) {
|
||||
|
||||
case 'kd':
|
||||
case 'ka':
|
||||
case 'ks':
|
||||
|
||||
// Diffuse color (color under white light) using RGB values
|
||||
|
||||
if ( this.options && this.options.normalizeRGB ) {
|
||||
|
||||
value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
|
||||
|
||||
}
|
||||
|
||||
if ( this.options && this.options.ignoreZeroRGBs ) {
|
||||
|
||||
if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
|
||||
|
||||
// ignore
|
||||
|
||||
save = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( save ) {
|
||||
|
||||
covmat[ lprop ] = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return converted;
|
||||
|
||||
},
|
||||
|
||||
preload: function () {
|
||||
|
||||
for ( var mn in this.materialsInfo ) {
|
||||
|
||||
this.create( mn );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getIndex: function ( materialName ) {
|
||||
|
||||
return this.nameLookup[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
getAsArray: function () {
|
||||
|
||||
var index = 0;
|
||||
|
||||
for ( var mn in this.materialsInfo ) {
|
||||
|
||||
this.materialsArray[ index ] = this.create( mn );
|
||||
this.nameLookup[ mn ] = index;
|
||||
index ++;
|
||||
|
||||
}
|
||||
|
||||
return this.materialsArray;
|
||||
|
||||
},
|
||||
|
||||
create: function ( materialName ) {
|
||||
|
||||
if ( this.materials[ materialName ] === undefined ) {
|
||||
|
||||
this.createMaterial_( materialName );
|
||||
|
||||
}
|
||||
|
||||
return this.materials[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
createMaterial_: function ( materialName ) {
|
||||
|
||||
// Create material
|
||||
|
||||
var scope = this;
|
||||
var mat = this.materialsInfo[ materialName ];
|
||||
var params = {
|
||||
|
||||
name: materialName,
|
||||
side: this.side
|
||||
|
||||
};
|
||||
|
||||
function resolveURL( baseUrl, url ) {
|
||||
|
||||
if ( typeof url !== 'string' || url === '' )
|
||||
return '';
|
||||
|
||||
// Absolute URL
|
||||
if ( /^https?:\/\//i.test( url ) ) return url;
|
||||
|
||||
return baseUrl + url;
|
||||
|
||||
}
|
||||
|
||||
function setMapForType( mapType, value ) {
|
||||
|
||||
if ( params[ mapType ] ) return; // Keep the first encountered texture
|
||||
|
||||
var texParams = scope.getTextureParams( value, params );
|
||||
var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) );
|
||||
|
||||
map.repeat.copy( texParams.scale );
|
||||
map.offset.copy( texParams.offset );
|
||||
|
||||
map.wrapS = scope.wrap;
|
||||
map.wrapT = scope.wrap;
|
||||
|
||||
params[ mapType ] = map;
|
||||
|
||||
}
|
||||
|
||||
for ( var prop in mat ) {
|
||||
|
||||
var value = mat[ prop ];
|
||||
var n;
|
||||
|
||||
if ( value === '' ) continue;
|
||||
|
||||
switch ( prop.toLowerCase() ) {
|
||||
|
||||
// Ns is material specular exponent
|
||||
|
||||
case 'kd':
|
||||
|
||||
// Diffuse color (color under white light) using RGB values
|
||||
|
||||
params.color = new THREE.Color().fromArray( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'ks':
|
||||
|
||||
// Specular color (color when light is reflected from shiny surface) using RGB values
|
||||
params.specular = new THREE.Color().fromArray( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_kd':
|
||||
|
||||
// Diffuse texture map
|
||||
|
||||
setMapForType( "map", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_ks':
|
||||
|
||||
// Specular map
|
||||
|
||||
setMapForType( "specularMap", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'norm':
|
||||
|
||||
setMapForType( "normalMap", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'map_bump':
|
||||
case 'bump':
|
||||
|
||||
// Bump texture map
|
||||
|
||||
setMapForType( "bumpMap", value );
|
||||
|
||||
break;
|
||||
|
||||
case 'ns':
|
||||
|
||||
// The specular exponent (defines the focus of the specular highlight)
|
||||
// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
|
||||
|
||||
params.shininess = parseFloat( value );
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
n = parseFloat( value );
|
||||
|
||||
if ( n < 1 ) {
|
||||
|
||||
params.opacity = n;
|
||||
params.transparent = true;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'tr':
|
||||
n = parseFloat( value );
|
||||
|
||||
if ( this.options && this.options.invertTrProperty ) n = 1 - n;
|
||||
|
||||
if ( n > 0 ) {
|
||||
|
||||
params.opacity = 1 - n;
|
||||
params.transparent = true;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
|
||||
return this.materials[ materialName ];
|
||||
|
||||
},
|
||||
|
||||
getTextureParams: function ( value, matParams ) {
|
||||
|
||||
var texParams = {
|
||||
|
||||
scale: new THREE.Vector2( 1, 1 ),
|
||||
offset: new THREE.Vector2( 0, 0 )
|
||||
|
||||
};
|
||||
|
||||
var items = value.split( /\s+/ );
|
||||
var pos;
|
||||
|
||||
pos = items.indexOf( '-bm' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
matParams.bumpScale = parseFloat( items[ pos + 1 ] );
|
||||
items.splice( pos, 2 );
|
||||
|
||||
}
|
||||
|
||||
pos = items.indexOf( '-s' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
|
||||
items.splice( pos, 4 ); // we expect 3 parameters here!
|
||||
|
||||
}
|
||||
|
||||
pos = items.indexOf( '-o' );
|
||||
|
||||
if ( pos >= 0 ) {
|
||||
|
||||
texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
|
||||
items.splice( pos, 4 ); // we expect 3 parameters here!
|
||||
|
||||
}
|
||||
|
||||
texParams.url = items.join( ' ' ).trim();
|
||||
return texParams;
|
||||
|
||||
},
|
||||
|
||||
loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
|
||||
|
||||
var texture;
|
||||
var loader = THREE.Loader.Handlers.get( url );
|
||||
var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
|
||||
|
||||
if ( loader === null ) {
|
||||
|
||||
loader = new THREE.TextureLoader( manager );
|
||||
|
||||
}
|
||||
|
||||
if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
|
||||
texture = loader.load( url, onLoad, onProgress, onError );
|
||||
|
||||
if ( mapping !== undefined ) texture.mapping = mapping;
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,793 +0,0 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
*/
|
||||
|
||||
THREE.OBJLoader = ( function () {
|
||||
|
||||
// o object_name | g group_name
|
||||
var object_pattern = /^[og]\s*(.+)?/;
|
||||
// mtllib file_reference
|
||||
var material_library_pattern = /^mtllib /;
|
||||
// usemtl material_name
|
||||
var material_use_pattern = /^usemtl /;
|
||||
|
||||
function ParserState() {
|
||||
|
||||
var state = {
|
||||
objects: [],
|
||||
object: {},
|
||||
|
||||
vertices: [],
|
||||
normals: [],
|
||||
colors: [],
|
||||
uvs: [],
|
||||
|
||||
materialLibraries: [],
|
||||
|
||||
startObject: function ( name, fromDeclaration ) {
|
||||
|
||||
// If the current object (initial from reset) is not from a g/o declaration in the parsed
|
||||
// file. We need to use it for the first parsed g/o to keep things in sync.
|
||||
if ( this.object && this.object.fromDeclaration === false ) {
|
||||
|
||||
this.object.name = name;
|
||||
this.object.fromDeclaration = ( fromDeclaration !== false );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
|
||||
|
||||
if ( this.object && typeof this.object._finalize === 'function' ) {
|
||||
|
||||
this.object._finalize( true );
|
||||
|
||||
}
|
||||
|
||||
this.object = {
|
||||
name: name || '',
|
||||
fromDeclaration: ( fromDeclaration !== false ),
|
||||
|
||||
geometry: {
|
||||
vertices: [],
|
||||
normals: [],
|
||||
colors: [],
|
||||
uvs: []
|
||||
},
|
||||
materials: [],
|
||||
smooth: true,
|
||||
|
||||
startMaterial: function ( name, libraries ) {
|
||||
|
||||
var previous = this._finalize( false );
|
||||
|
||||
// New usemtl declaration overwrites an inherited material, except if faces were declared
|
||||
// after the material, then it must be preserved for proper MultiMaterial continuation.
|
||||
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
|
||||
|
||||
this.materials.splice( previous.index, 1 );
|
||||
|
||||
}
|
||||
|
||||
var material = {
|
||||
index: this.materials.length,
|
||||
name: name || '',
|
||||
mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
|
||||
smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
|
||||
groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
|
||||
groupEnd: - 1,
|
||||
groupCount: - 1,
|
||||
inherited: false,
|
||||
|
||||
clone: function ( index ) {
|
||||
|
||||
var cloned = {
|
||||
index: ( typeof index === 'number' ? index : this.index ),
|
||||
name: this.name,
|
||||
mtllib: this.mtllib,
|
||||
smooth: this.smooth,
|
||||
groupStart: 0,
|
||||
groupEnd: - 1,
|
||||
groupCount: - 1,
|
||||
inherited: false
|
||||
};
|
||||
cloned.clone = this.clone.bind( cloned );
|
||||
return cloned;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.materials.push( material );
|
||||
|
||||
return material;
|
||||
|
||||
},
|
||||
|
||||
currentMaterial: function () {
|
||||
|
||||
if ( this.materials.length > 0 ) {
|
||||
|
||||
return this.materials[ this.materials.length - 1 ];
|
||||
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
},
|
||||
|
||||
_finalize: function ( end ) {
|
||||
|
||||
var lastMultiMaterial = this.currentMaterial();
|
||||
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
|
||||
|
||||
lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
|
||||
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
|
||||
lastMultiMaterial.inherited = false;
|
||||
|
||||
}
|
||||
|
||||
// Ignore objects tail materials if no face declarations followed them before a new o/g started.
|
||||
if ( end && this.materials.length > 1 ) {
|
||||
|
||||
for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) {
|
||||
|
||||
if ( this.materials[ mi ].groupCount <= 0 ) {
|
||||
|
||||
this.materials.splice( mi, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Guarantee at least one empty material, this makes the creation later more straight forward.
|
||||
if ( end && this.materials.length === 0 ) {
|
||||
|
||||
this.materials.push( {
|
||||
name: '',
|
||||
smooth: this.smooth
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
return lastMultiMaterial;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Inherit previous objects material.
|
||||
// Spec tells us that a declared material must be set to all objects until a new material is declared.
|
||||
// If a usemtl declaration is encountered while this new object is being parsed, it will
|
||||
// overwrite the inherited material. Exception being that there was already face declarations
|
||||
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
|
||||
|
||||
if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {
|
||||
|
||||
var declared = previousMaterial.clone( 0 );
|
||||
declared.inherited = true;
|
||||
this.object.materials.push( declared );
|
||||
|
||||
}
|
||||
|
||||
this.objects.push( this.object );
|
||||
|
||||
},
|
||||
|
||||
finalize: function () {
|
||||
|
||||
if ( this.object && typeof this.object._finalize === 'function' ) {
|
||||
|
||||
this.object._finalize( true );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
parseVertexIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
|
||||
|
||||
},
|
||||
|
||||
parseNormalIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
|
||||
|
||||
},
|
||||
|
||||
parseUVIndex: function ( value, len ) {
|
||||
|
||||
var index = parseInt( value, 10 );
|
||||
return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;
|
||||
|
||||
},
|
||||
|
||||
addVertex: function ( a, b, c ) {
|
||||
|
||||
var src = this.vertices;
|
||||
var dst = this.object.geometry.vertices;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
|
||||
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
|
||||
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addVertexPoint: function ( a ) {
|
||||
|
||||
var src = this.vertices;
|
||||
var dst = this.object.geometry.vertices;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addVertexLine: function ( a ) {
|
||||
|
||||
var src = this.vertices;
|
||||
var dst = this.object.geometry.vertices;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addNormal: function ( a, b, c ) {
|
||||
|
||||
var src = this.normals;
|
||||
var dst = this.object.geometry.normals;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
|
||||
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
|
||||
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addColor: function ( a, b, c ) {
|
||||
|
||||
var src = this.colors;
|
||||
var dst = this.object.geometry.colors;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
|
||||
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
|
||||
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
|
||||
|
||||
},
|
||||
|
||||
addUV: function ( a, b, c ) {
|
||||
|
||||
var src = this.uvs;
|
||||
var dst = this.object.geometry.uvs;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ] );
|
||||
dst.push( src[ b + 0 ], src[ b + 1 ] );
|
||||
dst.push( src[ c + 0 ], src[ c + 1 ] );
|
||||
|
||||
},
|
||||
|
||||
addUVLine: function ( a ) {
|
||||
|
||||
var src = this.uvs;
|
||||
var dst = this.object.geometry.uvs;
|
||||
|
||||
dst.push( src[ a + 0 ], src[ a + 1 ] );
|
||||
|
||||
},
|
||||
|
||||
addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {
|
||||
|
||||
var vLen = this.vertices.length;
|
||||
|
||||
var ia = this.parseVertexIndex( a, vLen );
|
||||
var ib = this.parseVertexIndex( b, vLen );
|
||||
var ic = this.parseVertexIndex( c, vLen );
|
||||
|
||||
this.addVertex( ia, ib, ic );
|
||||
|
||||
if ( ua !== undefined && ua !== '' ) {
|
||||
|
||||
var uvLen = this.uvs.length;
|
||||
ia = this.parseUVIndex( ua, uvLen );
|
||||
ib = this.parseUVIndex( ub, uvLen );
|
||||
ic = this.parseUVIndex( uc, uvLen );
|
||||
this.addUV( ia, ib, ic );
|
||||
|
||||
}
|
||||
|
||||
if ( na !== undefined && na !== '' ) {
|
||||
|
||||
// Normals are many times the same. If so, skip function call and parseInt.
|
||||
var nLen = this.normals.length;
|
||||
ia = this.parseNormalIndex( na, nLen );
|
||||
|
||||
ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
|
||||
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
|
||||
|
||||
this.addNormal( ia, ib, ic );
|
||||
|
||||
}
|
||||
|
||||
if ( this.colors.length > 0 ) {
|
||||
|
||||
this.addColor( ia, ib, ic );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
addPointGeometry: function ( vertices ) {
|
||||
|
||||
this.object.geometry.type = 'Points';
|
||||
|
||||
var vLen = this.vertices.length;
|
||||
|
||||
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
|
||||
|
||||
this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
addLineGeometry: function ( vertices, uvs ) {
|
||||
|
||||
this.object.geometry.type = 'Line';
|
||||
|
||||
var vLen = this.vertices.length;
|
||||
var uvLen = this.uvs.length;
|
||||
|
||||
for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
|
||||
|
||||
this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
|
||||
|
||||
}
|
||||
|
||||
for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {
|
||||
|
||||
this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
state.startObject( '', false );
|
||||
|
||||
return state;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function OBJLoader( manager ) {
|
||||
|
||||
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
|
||||
|
||||
this.materials = null;
|
||||
|
||||
}
|
||||
|
||||
OBJLoader.prototype = {
|
||||
|
||||
constructor: OBJLoader,
|
||||
|
||||
load: function ( url, onLoad, onProgress, onError ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
var loader = new THREE.FileLoader( scope.manager );
|
||||
loader.setPath( this.path );
|
||||
loader.load( url, function ( text ) {
|
||||
|
||||
onLoad( scope.parse( text ) );
|
||||
|
||||
}, onProgress, onError );
|
||||
|
||||
},
|
||||
|
||||
setPath: function ( value ) {
|
||||
|
||||
this.path = value;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
setMaterials: function ( materials ) {
|
||||
|
||||
this.materials = materials;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
parse: function ( text ) {
|
||||
|
||||
console.time( 'OBJLoader' );
|
||||
|
||||
var state = new ParserState();
|
||||
|
||||
if ( text.indexOf( '\r\n' ) !== - 1 ) {
|
||||
|
||||
// This is faster than String.split with regex that splits on both
|
||||
text = text.replace( /\r\n/g, '\n' );
|
||||
|
||||
}
|
||||
|
||||
if ( text.indexOf( '\\\n' ) !== - 1 ) {
|
||||
|
||||
// join lines separated by a line continuation character (\)
|
||||
text = text.replace( /\\\n/g, '' );
|
||||
|
||||
}
|
||||
|
||||
var lines = text.split( '\n' );
|
||||
var line = '', lineFirstChar = '';
|
||||
var lineLength = 0;
|
||||
var result = [];
|
||||
|
||||
// Faster to just trim left side of the line. Use if available.
|
||||
var trimLeft = ( typeof ''.trimLeft === 'function' );
|
||||
|
||||
for ( var i = 0, l = lines.length; i < l; i ++ ) {
|
||||
|
||||
line = lines[ i ];
|
||||
|
||||
line = trimLeft ? line.trimLeft() : line.trim();
|
||||
|
||||
lineLength = line.length;
|
||||
|
||||
if ( lineLength === 0 ) continue;
|
||||
|
||||
lineFirstChar = line.charAt( 0 );
|
||||
|
||||
// @todo invoke passed in handler if any
|
||||
if ( lineFirstChar === '#' ) continue;
|
||||
|
||||
if ( lineFirstChar === 'v' ) {
|
||||
|
||||
var data = line.split( /\s+/ );
|
||||
|
||||
switch ( data[ 0 ] ) {
|
||||
|
||||
case 'v':
|
||||
state.vertices.push(
|
||||
parseFloat( data[ 1 ] ),
|
||||
parseFloat( data[ 2 ] ),
|
||||
parseFloat( data[ 3 ] )
|
||||
);
|
||||
if ( data.length === 8 ) {
|
||||
|
||||
state.colors.push(
|
||||
parseFloat( data[ 4 ] ),
|
||||
parseFloat( data[ 5 ] ),
|
||||
parseFloat( data[ 6 ] )
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
break;
|
||||
case 'vn':
|
||||
state.normals.push(
|
||||
parseFloat( data[ 1 ] ),
|
||||
parseFloat( data[ 2 ] ),
|
||||
parseFloat( data[ 3 ] )
|
||||
);
|
||||
break;
|
||||
case 'vt':
|
||||
state.uvs.push(
|
||||
parseFloat( data[ 1 ] ),
|
||||
parseFloat( data[ 2 ] )
|
||||
);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} else if ( lineFirstChar === 'f' ) {
|
||||
|
||||
var lineData = line.substr( 1 ).trim();
|
||||
var vertexData = lineData.split( /\s+/ );
|
||||
var faceVertices = [];
|
||||
|
||||
// Parse the face vertex data into an easy to work with format
|
||||
|
||||
for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) {
|
||||
|
||||
var vertex = vertexData[ j ];
|
||||
|
||||
if ( vertex.length > 0 ) {
|
||||
|
||||
var vertexParts = vertex.split( '/' );
|
||||
faceVertices.push( vertexParts );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Draw an edge between the first vertex and all subsequent vertices to form an n-gon
|
||||
|
||||
var v1 = faceVertices[ 0 ];
|
||||
|
||||
for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
|
||||
|
||||
var v2 = faceVertices[ j ];
|
||||
var v3 = faceVertices[ j + 1 ];
|
||||
|
||||
state.addFace(
|
||||
v1[ 0 ], v2[ 0 ], v3[ 0 ],
|
||||
v1[ 1 ], v2[ 1 ], v3[ 1 ],
|
||||
v1[ 2 ], v2[ 2 ], v3[ 2 ]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
} else if ( lineFirstChar === 'l' ) {
|
||||
|
||||
var lineParts = line.substring( 1 ).trim().split( " " );
|
||||
var lineVertices = [], lineUVs = [];
|
||||
|
||||
if ( line.indexOf( "/" ) === - 1 ) {
|
||||
|
||||
lineVertices = lineParts;
|
||||
|
||||
} else {
|
||||
|
||||
for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) {
|
||||
|
||||
var parts = lineParts[ li ].split( "/" );
|
||||
|
||||
if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] );
|
||||
if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
state.addLineGeometry( lineVertices, lineUVs );
|
||||
|
||||
} else if ( lineFirstChar === 'p' ) {
|
||||
|
||||
var lineData = line.substr( 1 ).trim();
|
||||
var pointData = lineData.split( " " );
|
||||
|
||||
state.addPointGeometry( pointData );
|
||||
|
||||
} else if ( ( result = object_pattern.exec( line ) ) !== null ) {
|
||||
|
||||
// o object_name
|
||||
// or
|
||||
// g group_name
|
||||
|
||||
// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
||||
// var name = result[ 0 ].substr( 1 ).trim();
|
||||
var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
|
||||
|
||||
state.startObject( name );
|
||||
|
||||
} else if ( material_use_pattern.test( line ) ) {
|
||||
|
||||
// material
|
||||
|
||||
state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
|
||||
|
||||
} else if ( material_library_pattern.test( line ) ) {
|
||||
|
||||
// mtl file
|
||||
|
||||
state.materialLibraries.push( line.substring( 7 ).trim() );
|
||||
|
||||
} else if ( lineFirstChar === 's' ) {
|
||||
|
||||
result = line.split( ' ' );
|
||||
|
||||
// smooth shading
|
||||
|
||||
// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
|
||||
// but does not define a usemtl for each face set.
|
||||
// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
|
||||
// This requires some care to not create extra material on each smooth value for "normal" obj files.
|
||||
// where explicit usemtl defines geometry groups.
|
||||
// Example asset: examples/models/obj/cerberus/Cerberus.obj
|
||||
|
||||
/*
|
||||
* http://paulbourke.net/dataformats/obj/
|
||||
* or
|
||||
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
|
||||
*
|
||||
* From chapter "Grouping" Syntax explanation "s group_number":
|
||||
* "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
|
||||
* Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
|
||||
* surfaces, smoothing groups are either turned on or off; there is no difference between values greater
|
||||
* than 0."
|
||||
*/
|
||||
if ( result.length > 1 ) {
|
||||
|
||||
var value = result[ 1 ].trim().toLowerCase();
|
||||
state.object.smooth = ( value !== '0' && value !== 'off' );
|
||||
|
||||
} else {
|
||||
|
||||
// ZBrush can produce "s" lines #11707
|
||||
state.object.smooth = true;
|
||||
|
||||
}
|
||||
var material = state.object.currentMaterial();
|
||||
if ( material ) material.smooth = state.object.smooth;
|
||||
|
||||
} else {
|
||||
|
||||
// Handle null terminated files without exception
|
||||
if ( line === '\0' ) continue;
|
||||
|
||||
throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.finalize();
|
||||
|
||||
var container = new THREE.Group();
|
||||
container.materialLibraries = [].concat( state.materialLibraries );
|
||||
|
||||
for ( var i = 0, l = state.objects.length; i < l; i ++ ) {
|
||||
|
||||
var object = state.objects[ i ];
|
||||
var geometry = object.geometry;
|
||||
var materials = object.materials;
|
||||
var isLine = ( geometry.type === 'Line' );
|
||||
var isPoints = ( geometry.type === 'Points' );
|
||||
var hasVertexColors = false;
|
||||
|
||||
// Skip o/g line declarations that did not follow with any faces
|
||||
if ( geometry.vertices.length === 0 ) continue;
|
||||
|
||||
var buffergeometry = new THREE.BufferGeometry();
|
||||
|
||||
buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );
|
||||
|
||||
if ( geometry.normals.length > 0 ) {
|
||||
|
||||
buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );
|
||||
|
||||
} else {
|
||||
|
||||
buffergeometry.computeVertexNormals();
|
||||
|
||||
}
|
||||
|
||||
if ( geometry.colors.length > 0 ) {
|
||||
|
||||
hasVertexColors = true;
|
||||
buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( geometry.uvs.length > 0 ) {
|
||||
|
||||
buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
// Create materials
|
||||
|
||||
var createdMaterials = [];
|
||||
|
||||
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
|
||||
|
||||
var sourceMaterial = materials[ mi ];
|
||||
var material = undefined;
|
||||
|
||||
if ( this.materials !== null ) {
|
||||
|
||||
material = this.materials.create( sourceMaterial.name );
|
||||
|
||||
// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
|
||||
if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
|
||||
|
||||
var materialLine = new THREE.LineBasicMaterial();
|
||||
materialLine.copy( material );
|
||||
materialLine.lights = false; // TOFIX
|
||||
material = materialLine;
|
||||
|
||||
} else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) {
|
||||
|
||||
var materialPoints = new THREE.PointsMaterial( { size: 10, sizeAttenuation: false } );
|
||||
materialLine.copy( material );
|
||||
material = materialPoints;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! material ) {
|
||||
|
||||
if ( isLine ) {
|
||||
|
||||
material = new THREE.LineBasicMaterial();
|
||||
|
||||
} else if ( isPoints ) {
|
||||
|
||||
material = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } );
|
||||
|
||||
} else {
|
||||
|
||||
material = new THREE.MeshPhongMaterial();
|
||||
|
||||
}
|
||||
|
||||
material.name = sourceMaterial.name;
|
||||
|
||||
}
|
||||
|
||||
material.flatShading = sourceMaterial.smooth ? false : true;
|
||||
material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors;
|
||||
|
||||
createdMaterials.push( material );
|
||||
|
||||
}
|
||||
|
||||
// Create mesh
|
||||
|
||||
var mesh;
|
||||
|
||||
if ( createdMaterials.length > 1 ) {
|
||||
|
||||
for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
|
||||
|
||||
var sourceMaterial = materials[ mi ];
|
||||
buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );
|
||||
|
||||
}
|
||||
|
||||
if ( isLine ) {
|
||||
|
||||
mesh = new THREE.LineSegments( buffergeometry, createdMaterials );
|
||||
|
||||
} else if ( isPoints ) {
|
||||
|
||||
mesh = new THREE.Points( buffergeometry, createdMaterials );
|
||||
|
||||
} else {
|
||||
|
||||
mesh = new THREE.Mesh( buffergeometry, createdMaterials );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( isLine ) {
|
||||
|
||||
mesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] );
|
||||
|
||||
} else if ( isPoints ) {
|
||||
|
||||
mesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] );
|
||||
|
||||
} else {
|
||||
|
||||
mesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mesh.name = object.name;
|
||||
|
||||
container.add( mesh );
|
||||
|
||||
}
|
||||
|
||||
console.timeEnd( 'OBJLoader' );
|
||||
|
||||
return container;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return OBJLoader;
|
||||
|
||||
} )();
|
||||
@@ -1,571 +0,0 @@
|
||||
/**
|
||||
* @author spidersharma / http://eduperiment.com/
|
||||
*/
|
||||
|
||||
THREE.OutlinePass = function ( resolution, scene, camera, selectedObjects ) {
|
||||
|
||||
this.renderScene = scene;
|
||||
this.renderCamera = camera;
|
||||
this.selectedObjects = selectedObjects !== undefined ? selectedObjects : [];
|
||||
this.visibleEdgeColor = new THREE.Color( 1, 1, 1 );
|
||||
this.hiddenEdgeColor = new THREE.Color( 0.1, 0.04, 0.02 );
|
||||
this.edgeGlow = 0.0;
|
||||
this.usePatternTexture = false;
|
||||
this.edgeThickness = 1.0;
|
||||
this.edgeStrength = 3.0;
|
||||
this.downSampleRatio = 2;
|
||||
this.pulsePeriod = 0;
|
||||
|
||||
THREE.Pass.call( this );
|
||||
|
||||
this.resolution = ( resolution !== undefined ) ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 );
|
||||
|
||||
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
|
||||
|
||||
var resx = Math.round( this.resolution.x / this.downSampleRatio );
|
||||
var resy = Math.round( this.resolution.y / this.downSampleRatio );
|
||||
|
||||
this.maskBufferMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff } );
|
||||
this.maskBufferMaterial.side = THREE.DoubleSide;
|
||||
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
||||
this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask";
|
||||
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
|
||||
|
||||
this.depthMaterial = new THREE.MeshDepthMaterial();
|
||||
this.depthMaterial.side = THREE.DoubleSide;
|
||||
this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
|
||||
this.depthMaterial.blending = THREE.NoBlending;
|
||||
|
||||
this.prepareMaskMaterial = this.getPrepareMaskMaterial();
|
||||
this.prepareMaskMaterial.side = THREE.DoubleSide;
|
||||
this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ( this.prepareMaskMaterial.fragmentShader, this.renderCamera );
|
||||
|
||||
this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
|
||||
this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth";
|
||||
this.renderTargetDepthBuffer.texture.generateMipmaps = false;
|
||||
|
||||
this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample";
|
||||
this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;
|
||||
|
||||
this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1";
|
||||
this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
|
||||
this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
||||
this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2";
|
||||
this.renderTargetBlurBuffer2.texture.generateMipmaps = false;
|
||||
|
||||
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial();
|
||||
this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
|
||||
this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1";
|
||||
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
|
||||
this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
|
||||
this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2";
|
||||
this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;
|
||||
|
||||
var MAX_EDGE_THICKNESS = 4;
|
||||
var MAX_EDGE_GLOW = 4;
|
||||
|
||||
this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS );
|
||||
this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );
|
||||
this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = 1;
|
||||
this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW );
|
||||
this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( Math.round( resx / 2 ), Math.round( resy / 2 ) );
|
||||
this.separableBlurMaterial2.uniforms[ "kernelRadius" ].value = MAX_EDGE_GLOW;
|
||||
|
||||
// Overlay material
|
||||
this.overlayMaterial = this.getOverlayMaterial();
|
||||
|
||||
// copy material
|
||||
if ( THREE.CopyShader === undefined )
|
||||
console.error( "THREE.OutlinePass relies on THREE.CopyShader" );
|
||||
|
||||
var copyShader = THREE.CopyShader;
|
||||
|
||||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
|
||||
this.copyUniforms[ "opacity" ].value = 1.0;
|
||||
|
||||
this.materialCopy = new THREE.ShaderMaterial( {
|
||||
uniforms: this.copyUniforms,
|
||||
vertexShader: copyShader.vertexShader,
|
||||
fragmentShader: copyShader.fragmentShader,
|
||||
blending: THREE.NoBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
transparent: true
|
||||
} );
|
||||
|
||||
this.enabled = true;
|
||||
this.needsSwap = false;
|
||||
|
||||
this.oldClearColor = new THREE.Color();
|
||||
this.oldClearAlpha = 1;
|
||||
|
||||
this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||
this.scene = new THREE.Scene();
|
||||
|
||||
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
|
||||
this.quad.frustumCulled = false; // Avoid getting clipped
|
||||
this.scene.add( this.quad );
|
||||
|
||||
this.tempPulseColor1 = new THREE.Color();
|
||||
this.tempPulseColor2 = new THREE.Color();
|
||||
this.textureMatrix = new THREE.Matrix4();
|
||||
|
||||
function replaceDepthToViewZ( string, camera ) {
|
||||
|
||||
var type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';
|
||||
|
||||
return string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
|
||||
|
||||
constructor: THREE.OutlinePass,
|
||||
|
||||
dispose: function () {
|
||||
|
||||
this.renderTargetMaskBuffer.dispose();
|
||||
this.renderTargetDepthBuffer.dispose();
|
||||
this.renderTargetMaskDownSampleBuffer.dispose();
|
||||
this.renderTargetBlurBuffer1.dispose();
|
||||
this.renderTargetBlurBuffer2.dispose();
|
||||
this.renderTargetEdgeBuffer1.dispose();
|
||||
this.renderTargetEdgeBuffer2.dispose();
|
||||
|
||||
},
|
||||
|
||||
setSize: function ( width, height ) {
|
||||
|
||||
this.renderTargetMaskBuffer.setSize( width, height );
|
||||
|
||||
var resx = Math.round( width / this.downSampleRatio );
|
||||
var resy = Math.round( height / this.downSampleRatio );
|
||||
this.renderTargetMaskDownSampleBuffer.setSize( resx, resy );
|
||||
this.renderTargetBlurBuffer1.setSize( resx, resy );
|
||||
this.renderTargetEdgeBuffer1.setSize( resx, resy );
|
||||
this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );
|
||||
|
||||
resx = Math.round( resx / 2 );
|
||||
resy = Math.round( resy / 2 );
|
||||
|
||||
this.renderTargetBlurBuffer2.setSize( resx, resy );
|
||||
this.renderTargetEdgeBuffer2.setSize( resx, resy );
|
||||
|
||||
this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );
|
||||
|
||||
},
|
||||
|
||||
changeVisibilityOfSelectedObjects: function ( bVisible ) {
|
||||
|
||||
function gatherSelectedMeshesCallBack( object ) {
|
||||
|
||||
if ( object.isMesh ) {
|
||||
|
||||
if ( bVisible ) {
|
||||
|
||||
object.visible = object.userData.oldVisible;
|
||||
delete object.userData.oldVisible;
|
||||
|
||||
} else {
|
||||
|
||||
object.userData.oldVisible = object.visible;
|
||||
object.visible = bVisible;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < this.selectedObjects.length; i ++ ) {
|
||||
|
||||
var selectedObject = this.selectedObjects[ i ];
|
||||
selectedObject.traverse( gatherSelectedMeshesCallBack );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
changeVisibilityOfNonSelectedObjects: function ( bVisible ) {
|
||||
|
||||
var selectedMeshes = [];
|
||||
|
||||
function gatherSelectedMeshesCallBack( object ) {
|
||||
|
||||
if ( object.isMesh ) selectedMeshes.push( object );
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < this.selectedObjects.length; i ++ ) {
|
||||
|
||||
var selectedObject = this.selectedObjects[ i ];
|
||||
selectedObject.traverse( gatherSelectedMeshesCallBack );
|
||||
|
||||
}
|
||||
|
||||
function VisibilityChangeCallBack( object ) {
|
||||
|
||||
if ( object.isMesh || object.isLine || object.isSprite ) {
|
||||
|
||||
var bFound = false;
|
||||
|
||||
for ( var i = 0; i < selectedMeshes.length; i ++ ) {
|
||||
|
||||
var selectedObjectId = selectedMeshes[ i ].id;
|
||||
|
||||
if ( selectedObjectId === object.id ) {
|
||||
|
||||
bFound = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! bFound ) {
|
||||
|
||||
var visibility = object.visible;
|
||||
|
||||
if ( ! bVisible || object.bVisible ) object.visible = bVisible;
|
||||
|
||||
object.bVisible = visibility;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.renderScene.traverse( VisibilityChangeCallBack );
|
||||
|
||||
},
|
||||
|
||||
updateTextureMatrix: function () {
|
||||
|
||||
this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5,
|
||||
0.0, 0.5, 0.0, 0.5,
|
||||
0.0, 0.0, 0.5, 0.5,
|
||||
0.0, 0.0, 0.0, 1.0 );
|
||||
this.textureMatrix.multiply( this.renderCamera.projectionMatrix );
|
||||
this.textureMatrix.multiply( this.renderCamera.matrixWorldInverse );
|
||||
|
||||
},
|
||||
|
||||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
||||
|
||||
if ( this.selectedObjects.length > 0 ) {
|
||||
|
||||
this.oldClearColor.copy( renderer.getClearColor() );
|
||||
this.oldClearAlpha = renderer.getClearAlpha();
|
||||
var oldAutoClear = renderer.autoClear;
|
||||
|
||||
renderer.autoClear = false;
|
||||
|
||||
if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST );
|
||||
|
||||
renderer.setClearColor( 0xffffff, 1 );
|
||||
|
||||
// Make selected objects invisible
|
||||
this.changeVisibilityOfSelectedObjects( false );
|
||||
|
||||
var currentBackground = this.renderScene.background;
|
||||
this.renderScene.background = null;
|
||||
|
||||
// 1. Draw Non Selected objects in the depth buffer
|
||||
this.renderScene.overrideMaterial = this.depthMaterial;
|
||||
renderer.render( this.renderScene, this.renderCamera, this.renderTargetDepthBuffer, true );
|
||||
|
||||
// Make selected objects visible
|
||||
this.changeVisibilityOfSelectedObjects( true );
|
||||
|
||||
// Update Texture Matrix for Depth compare
|
||||
this.updateTextureMatrix();
|
||||
|
||||
// Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
|
||||
this.changeVisibilityOfNonSelectedObjects( false );
|
||||
this.renderScene.overrideMaterial = this.prepareMaskMaterial;
|
||||
this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( this.renderCamera.near, this.renderCamera.far );
|
||||
this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
|
||||
this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
|
||||
renderer.render( this.renderScene, this.renderCamera, this.renderTargetMaskBuffer, true );
|
||||
this.renderScene.overrideMaterial = null;
|
||||
this.changeVisibilityOfNonSelectedObjects( true );
|
||||
|
||||
this.renderScene.background = currentBackground;
|
||||
|
||||
// 2. Downsample to Half resolution
|
||||
this.quad.material = this.materialCopy;
|
||||
this.copyUniforms[ "tDiffuse" ].value = this.renderTargetMaskBuffer.texture;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetMaskDownSampleBuffer, true );
|
||||
|
||||
this.tempPulseColor1.copy( this.visibleEdgeColor );
|
||||
this.tempPulseColor2.copy( this.hiddenEdgeColor );
|
||||
|
||||
if ( this.pulsePeriod > 0 ) {
|
||||
|
||||
var scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2;
|
||||
this.tempPulseColor1.multiplyScalar( scalar );
|
||||
this.tempPulseColor2.multiplyScalar( scalar );
|
||||
|
||||
}
|
||||
|
||||
// 3. Apply Edge Detection Pass
|
||||
this.quad.material = this.edgeDetectionMaterial;
|
||||
this.edgeDetectionMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskDownSampleBuffer.texture;
|
||||
this.edgeDetectionMaterial.uniforms[ "texSize" ].value = new THREE.Vector2( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );
|
||||
this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1;
|
||||
this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true );
|
||||
|
||||
// 4. Apply Blur on Half res
|
||||
this.quad.material = this.separableBlurMaterial1;
|
||||
this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
|
||||
this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = this.edgeThickness;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer1, true );
|
||||
this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer1.texture;
|
||||
this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true );
|
||||
|
||||
// Apply Blur on quarter res
|
||||
this.quad.material = this.separableBlurMaterial2;
|
||||
this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer2, true );
|
||||
this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer2.texture;
|
||||
this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
|
||||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer2, true );
|
||||
|
||||
// Blend it additively over the input texture
|
||||
this.quad.material = this.overlayMaterial;
|
||||
this.overlayMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskBuffer.texture;
|
||||
this.overlayMaterial.uniforms[ "edgeTexture1" ].value = this.renderTargetEdgeBuffer1.texture;
|
||||
this.overlayMaterial.uniforms[ "edgeTexture2" ].value = this.renderTargetEdgeBuffer2.texture;
|
||||
this.overlayMaterial.uniforms[ "patternTexture" ].value = this.patternTexture;
|
||||
this.overlayMaterial.uniforms[ "edgeStrength" ].value = this.edgeStrength;
|
||||
this.overlayMaterial.uniforms[ "edgeGlow" ].value = this.edgeGlow;
|
||||
this.overlayMaterial.uniforms[ "usePatternTexture" ].value = this.usePatternTexture;
|
||||
|
||||
|
||||
if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST );
|
||||
|
||||
renderer.render( this.scene, this.camera, readBuffer, false );
|
||||
|
||||
renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
|
||||
renderer.autoClear = oldAutoClear;
|
||||
|
||||
}
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
this.quad.material = this.materialCopy;
|
||||
this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture;
|
||||
renderer.render( this.scene, this.camera );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getPrepareMaskMaterial: function () {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
"depthTexture": { value: null },
|
||||
"cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
||||
"textureMatrix": { value: new THREE.Matrix4() }
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
'varying vec4 projTexCoord;',
|
||||
'varying vec4 vPosition;',
|
||||
'uniform mat4 textureMatrix;',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' vPosition = modelViewMatrix * vec4( position, 1.0 );',
|
||||
' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
|
||||
' projTexCoord = textureMatrix * worldPosition;',
|
||||
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
|
||||
|
||||
'}'
|
||||
].join( '\n' ),
|
||||
|
||||
fragmentShader: [
|
||||
'#include <packing>',
|
||||
'varying vec4 vPosition;',
|
||||
'varying vec4 projTexCoord;',
|
||||
'uniform sampler2D depthTexture;',
|
||||
'uniform vec2 cameraNearFar;',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));',
|
||||
' float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );',
|
||||
' float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;',
|
||||
' gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);',
|
||||
|
||||
'}'
|
||||
].join( '\n' )
|
||||
|
||||
} );
|
||||
|
||||
},
|
||||
|
||||
getEdgeDetectionMaterial: function () {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
"maskTexture": { value: null },
|
||||
"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
||||
"visibleEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) },
|
||||
"hiddenEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) },
|
||||
},
|
||||
|
||||
vertexShader:
|
||||
"varying vec2 vUv;\n\
|
||||
void main() {\n\
|
||||
vUv = uv;\n\
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
|
||||
}",
|
||||
|
||||
fragmentShader:
|
||||
"varying vec2 vUv;\
|
||||
uniform sampler2D maskTexture;\
|
||||
uniform vec2 texSize;\
|
||||
uniform vec3 visibleEdgeColor;\
|
||||
uniform vec3 hiddenEdgeColor;\
|
||||
\
|
||||
void main() {\n\
|
||||
vec2 invSize = 1.0 / texSize;\
|
||||
vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);\
|
||||
vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);\
|
||||
vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);\
|
||||
vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);\
|
||||
vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);\
|
||||
float diff1 = (c1.r - c2.r)*0.5;\
|
||||
float diff2 = (c3.r - c4.r)*0.5;\
|
||||
float d = length( vec2(diff1, diff2) );\
|
||||
float a1 = min(c1.g, c2.g);\
|
||||
float a2 = min(c3.g, c4.g);\
|
||||
float visibilityFactor = min(a1, a2);\
|
||||
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;\
|
||||
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);\
|
||||
}"
|
||||
} );
|
||||
|
||||
},
|
||||
|
||||
getSeperableBlurMaterial: function ( maxRadius ) {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
|
||||
defines: {
|
||||
"MAX_RADIUS": maxRadius,
|
||||
},
|
||||
|
||||
uniforms: {
|
||||
"colorTexture": { value: null },
|
||||
"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
||||
"direction": { value: new THREE.Vector2( 0.5, 0.5 ) },
|
||||
"kernelRadius": { value: 1.0 }
|
||||
},
|
||||
|
||||
vertexShader:
|
||||
"varying vec2 vUv;\n\
|
||||
void main() {\n\
|
||||
vUv = uv;\n\
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
|
||||
}",
|
||||
|
||||
fragmentShader:
|
||||
"#include <common>\
|
||||
varying vec2 vUv;\
|
||||
uniform sampler2D colorTexture;\
|
||||
uniform vec2 texSize;\
|
||||
uniform vec2 direction;\
|
||||
uniform float kernelRadius;\
|
||||
\
|
||||
float gaussianPdf(in float x, in float sigma) {\
|
||||
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\
|
||||
}\
|
||||
void main() {\
|
||||
vec2 invSize = 1.0 / texSize;\
|
||||
float weightSum = gaussianPdf(0.0, kernelRadius);\
|
||||
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\
|
||||
vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\
|
||||
vec2 uvOffset = delta;\
|
||||
for( int i = 1; i <= MAX_RADIUS; i ++ ) {\
|
||||
float w = gaussianPdf(uvOffset.x, kernelRadius);\
|
||||
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\
|
||||
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\
|
||||
diffuseSum += ((sample1 + sample2) * w);\
|
||||
weightSum += (2.0 * w);\
|
||||
uvOffset += delta;\
|
||||
}\
|
||||
gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\
|
||||
}"
|
||||
} );
|
||||
|
||||
},
|
||||
|
||||
getOverlayMaterial: function () {
|
||||
|
||||
return new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
"maskTexture": { value: null },
|
||||
"edgeTexture1": { value: null },
|
||||
"edgeTexture2": { value: null },
|
||||
"patternTexture": { value: null },
|
||||
"edgeStrength": { value: 1.0 },
|
||||
"edgeGlow": { value: 1.0 },
|
||||
"usePatternTexture": { value: 0.0 }
|
||||
},
|
||||
|
||||
vertexShader:
|
||||
"varying vec2 vUv;\n\
|
||||
void main() {\n\
|
||||
vUv = uv;\n\
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
|
||||
}",
|
||||
|
||||
fragmentShader:
|
||||
"varying vec2 vUv;\
|
||||
uniform sampler2D maskTexture;\
|
||||
uniform sampler2D edgeTexture1;\
|
||||
uniform sampler2D edgeTexture2;\
|
||||
uniform sampler2D patternTexture;\
|
||||
uniform float edgeStrength;\
|
||||
uniform float edgeGlow;\
|
||||
uniform bool usePatternTexture;\
|
||||
\
|
||||
void main() {\
|
||||
vec4 edgeValue1 = texture2D(edgeTexture1, vUv);\
|
||||
vec4 edgeValue2 = texture2D(edgeTexture2, vUv);\
|
||||
vec4 maskColor = texture2D(maskTexture, vUv);\
|
||||
vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);\
|
||||
float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;\
|
||||
vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;\
|
||||
vec4 finalColor = edgeStrength * maskColor.r * edgeValue;\
|
||||
if(usePatternTexture)\
|
||||
finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);\
|
||||
gl_FragColor = finalColor;\
|
||||
}",
|
||||
blending: THREE.AdditiveBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
transparent: true
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
THREE.OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
|
||||
THREE.OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );
|
||||
|
Before Width: | Height: | Size: 960 B |
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
|
||||
|
||||
THREE.Pass.call( this );
|
||||
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
|
||||
this.overrideMaterial = overrideMaterial;
|
||||
|
||||
this.clearColor = clearColor;
|
||||
this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;
|
||||
|
||||
this.clear = true;
|
||||
this.clearDepth = false;
|
||||
this.needsSwap = false;
|
||||
|
||||
};
|
||||
|
||||
THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
|
||||
|
||||
constructor: THREE.RenderPass,
|
||||
|
||||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
||||
|
||||
var oldAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
|
||||
this.scene.overrideMaterial = this.overrideMaterial;
|
||||
|
||||
var oldClearColor, oldClearAlpha;
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
oldClearColor = renderer.getClearColor().getHex();
|
||||
oldClearAlpha = renderer.getClearAlpha();
|
||||
|
||||
renderer.setClearColor( this.clearColor, this.clearAlpha );
|
||||
|
||||
}
|
||||
|
||||
if ( this.clearDepth ) {
|
||||
|
||||
renderer.clearDepth();
|
||||
|
||||
}
|
||||
|
||||
renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear );
|
||||
|
||||
if ( this.clearColor ) {
|
||||
|
||||
renderer.setClearColor( oldClearColor, oldClearAlpha );
|
||||
|
||||
}
|
||||
|
||||
this.scene.overrideMaterial = null;
|
||||
renderer.autoClear = oldAutoClear;
|
||||
}
|
||||
|
||||
} );
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.ShaderPass = function ( shader, textureID ) {
|
||||
|
||||
THREE.Pass.call( this );
|
||||
|
||||
this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";
|
||||
|
||||
if ( shader instanceof THREE.ShaderMaterial ) {
|
||||
|
||||
this.uniforms = shader.uniforms;
|
||||
|
||||
this.material = shader;
|
||||
|
||||
} else if ( shader ) {
|
||||
|
||||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||
|
||||
this.material = new THREE.ShaderMaterial( {
|
||||
|
||||
defines: Object.assign( {}, shader.defines ),
|
||||
uniforms: this.uniforms,
|
||||
vertexShader: shader.vertexShader,
|
||||
fragmentShader: shader.fragmentShader
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||
this.scene = new THREE.Scene();
|
||||
|
||||
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
|
||||
this.quad.frustumCulled = false; // Avoid getting clipped
|
||||
this.scene.add( this.quad );
|
||||
|
||||
};
|
||||
|
||||
THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {
|
||||
|
||||
constructor: THREE.ShaderPass,
|
||||
|
||||
render: function( renderer, writeBuffer, readBuffer, delta, maskActive ) {
|
||||
|
||||
if ( this.uniforms[ this.textureID ] ) {
|
||||
|
||||
this.uniforms[ this.textureID ].value = readBuffer.texture;
|
||||
|
||||
}
|
||||
|
||||
this.quad.material = this.material;
|
||||
|
||||
if ( this.renderToScreen ) {
|
||||
|
||||
renderer.render( this.scene, this.camera );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.render( this.scene, this.camera, writeBuffer, this.clear );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
@@ -1,519 +0,0 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
var BACK, COPLANAR, EPSILON, FRONT, SPANNING, returning,
|
||||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
__slice = [].slice,
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
||||
EPSILON = 1e-5;
|
||||
|
||||
COPLANAR = 0;
|
||||
|
||||
FRONT = 1;
|
||||
|
||||
BACK = 2;
|
||||
|
||||
SPANNING = 3;
|
||||
|
||||
returning = function(value, fn) {
|
||||
fn();
|
||||
return value;
|
||||
};
|
||||
|
||||
window.ThreeBSP = (function() {
|
||||
function ThreeBSP(treeIsh, matrix) {
|
||||
this.matrix = matrix;
|
||||
this.intersect = __bind(this.intersect, this);
|
||||
this.union = __bind(this.union, this);
|
||||
this.subtract = __bind(this.subtract, this);
|
||||
this.toGeometry = __bind(this.toGeometry, this);
|
||||
this.toMesh = __bind(this.toMesh, this);
|
||||
this.toTree = __bind(this.toTree, this);
|
||||
if (this.matrix == null) {
|
||||
this.matrix = new THREE.Matrix4();
|
||||
}
|
||||
this.tree = this.toTree(treeIsh);
|
||||
}
|
||||
|
||||
ThreeBSP.prototype.toTree = function(treeIsh) {
|
||||
var face, geometry, i, polygons, _fn, _i, _len, _ref,
|
||||
_this = this;
|
||||
if (treeIsh instanceof ThreeBSP.Node) {
|
||||
return treeIsh;
|
||||
}
|
||||
polygons = [];
|
||||
geometry = treeIsh instanceof THREE.Geometry ? treeIsh : treeIsh instanceof THREE.Mesh ? (treeIsh.updateMatrix(), this.matrix = treeIsh.matrix.clone(), treeIsh.geometry) : void 0;
|
||||
_ref = geometry.faces;
|
||||
_fn = function(face, i) {
|
||||
var faceVertexUvs, idx, polygon, vIndex, vName, vertex, _j, _len1, _ref1, _ref2;
|
||||
faceVertexUvs = (_ref1 = geometry.faceVertexUvs) != null ? _ref1[0][i] : void 0;
|
||||
if (faceVertexUvs == null) {
|
||||
faceVertexUvs = [new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()];
|
||||
}
|
||||
polygon = new ThreeBSP.Polygon();
|
||||
_ref2 = ['a', 'b', 'c', 'd'];
|
||||
for (vIndex = _j = 0, _len1 = _ref2.length; _j < _len1; vIndex = ++_j) {
|
||||
vName = _ref2[vIndex];
|
||||
if ((idx = face[vName]) != null) {
|
||||
vertex = geometry.vertices[idx];
|
||||
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], new THREE.Vector2(faceVertexUvs[vIndex].x, faceVertexUvs[vIndex].y));
|
||||
vertex.applyMatrix4(_this.matrix);
|
||||
polygon.vertices.push(vertex);
|
||||
}
|
||||
}
|
||||
return polygons.push(polygon.calculateProperties());
|
||||
};
|
||||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
||||
face = _ref[i];
|
||||
_fn(face, i);
|
||||
}
|
||||
return new ThreeBSP.Node(polygons);
|
||||
};
|
||||
|
||||
ThreeBSP.prototype.toMesh = function(material) {
|
||||
var geometry, mesh,
|
||||
_this = this;
|
||||
if (material == null) {
|
||||
material = new THREE.MeshNormalMaterial();
|
||||
}
|
||||
geometry = this.toGeometry();
|
||||
return returning((mesh = new THREE.Mesh(geometry, material)), function() {
|
||||
mesh.position.setFromMatrixPosition(_this.matrix);
|
||||
return mesh.rotation.setFromRotationMatrix(_this.matrix);
|
||||
});
|
||||
};
|
||||
|
||||
ThreeBSP.prototype.toGeometry = function() {
|
||||
var geometry, matrix,
|
||||
_this = this;
|
||||
matrix = new THREE.Matrix4().getInverse(this.matrix);
|
||||
return returning((geometry = new THREE.Geometry()), function() {
|
||||
var face, idx, polyVerts, polygon, v, vertUvs, verts, _i, _len, _ref, _results;
|
||||
_ref = _this.tree.allPolygons();
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
polygon = _ref[_i];
|
||||
polyVerts = (function() {
|
||||
var _j, _len1, _ref1, _results1;
|
||||
_ref1 = polygon.vertices;
|
||||
_results1 = [];
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
v = _ref1[_j];
|
||||
_results1.push(v.clone().applyMatrix4(matrix));
|
||||
}
|
||||
return _results1;
|
||||
})();
|
||||
_results.push((function() {
|
||||
var _j, _ref1, _results1;
|
||||
_results1 = [];
|
||||
for (idx = _j = 2, _ref1 = polyVerts.length; 2 <= _ref1 ? _j < _ref1 : _j > _ref1; idx = 2 <= _ref1 ? ++_j : --_j) {
|
||||
verts = [polyVerts[0], polyVerts[idx - 1], polyVerts[idx]];
|
||||
vertUvs = (function() {
|
||||
var _k, _len1, _ref2, _ref3, _results2;
|
||||
_results2 = [];
|
||||
for (_k = 0, _len1 = verts.length; _k < _len1; _k++) {
|
||||
v = verts[_k];
|
||||
_results2.push(new THREE.Vector2((_ref2 = v.uv) != null ? _ref2.x : void 0, (_ref3 = v.uv) != null ? _ref3.y : void 0));
|
||||
}
|
||||
return _results2;
|
||||
})();
|
||||
face = (function(func, args, ctor) {
|
||||
ctor.prototype = func.prototype;
|
||||
var child = new ctor, result = func.apply(child, args);
|
||||
return Object(result) === result ? result : child;
|
||||
})(THREE.Face3, __slice.call((function() {
|
||||
var _k, _len1, _results2;
|
||||
_results2 = [];
|
||||
for (_k = 0, _len1 = verts.length; _k < _len1; _k++) {
|
||||
v = verts[_k];
|
||||
_results2.push(geometry.vertices.push(v) - 1);
|
||||
}
|
||||
return _results2;
|
||||
})()).concat([polygon.normal.clone()]), function(){});
|
||||
geometry.faces.push(face);
|
||||
_results1.push(geometry.faceVertexUvs[0].push(vertUvs));
|
||||
}
|
||||
return _results1;
|
||||
})());
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
};
|
||||
|
||||
ThreeBSP.prototype.subtract = function(other) {
|
||||
var them, us, _ref;
|
||||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1];
|
||||
us.invert().clipTo(them);
|
||||
them.clipTo(us).invert().clipTo(us).invert();
|
||||
return new ThreeBSP(us.build(them.allPolygons()).invert(), this.matrix);
|
||||
};
|
||||
|
||||
ThreeBSP.prototype.union = function(other) {
|
||||
var them, us, _ref;
|
||||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1];
|
||||
us.clipTo(them);
|
||||
them.clipTo(us).invert().clipTo(us).invert();
|
||||
return new ThreeBSP(us.build(them.allPolygons()), this.matrix);
|
||||
};
|
||||
|
||||
ThreeBSP.prototype.intersect = function(other) {
|
||||
var them, us, _ref;
|
||||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1];
|
||||
them.clipTo(us.invert()).invert().clipTo(us.clipTo(them));
|
||||
return new ThreeBSP(us.build(them.allPolygons()).invert(), this.matrix);
|
||||
};
|
||||
|
||||
return ThreeBSP;
|
||||
|
||||
})();
|
||||
|
||||
ThreeBSP.Vertex = (function(_super) {
|
||||
__extends(Vertex, _super);
|
||||
|
||||
function Vertex(x, y, z, normal, uv) {
|
||||
this.normal = normal != null ? normal : new THREE.Vector3();
|
||||
this.uv = uv != null ? uv : new THREE.Vector2();
|
||||
this.interpolate = __bind(this.interpolate, this);
|
||||
this.lerp = __bind(this.lerp, this);
|
||||
Vertex.__super__.constructor.call(this, x, y, z);
|
||||
}
|
||||
|
||||
Vertex.prototype.clone = function() {
|
||||
return new ThreeBSP.Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone());
|
||||
};
|
||||
|
||||
Vertex.prototype.lerp = function(v, alpha) {
|
||||
var _this = this;
|
||||
return returning(Vertex.__super__.lerp.apply(this, arguments), function() {
|
||||
_this.uv.add(v.uv.clone().sub(_this.uv).multiplyScalar(alpha));
|
||||
return _this.normal.lerp(v, alpha);
|
||||
});
|
||||
};
|
||||
|
||||
Vertex.prototype.interpolate = function() {
|
||||
var args, _ref;
|
||||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
||||
return (_ref = this.clone()).lerp.apply(_ref, args);
|
||||
};
|
||||
|
||||
return Vertex;
|
||||
|
||||
})(THREE.Vector3);
|
||||
|
||||
ThreeBSP.Polygon = (function() {
|
||||
function Polygon(vertices, normal, w) {
|
||||
this.vertices = vertices != null ? vertices : [];
|
||||
this.normal = normal;
|
||||
this.w = w;
|
||||
this.subdivide = __bind(this.subdivide, this);
|
||||
this.tessellate = __bind(this.tessellate, this);
|
||||
this.classifySide = __bind(this.classifySide, this);
|
||||
this.classifyVertex = __bind(this.classifyVertex, this);
|
||||
this.invert = __bind(this.invert, this);
|
||||
this.clone = __bind(this.clone, this);
|
||||
this.calculateProperties = __bind(this.calculateProperties, this);
|
||||
if (this.vertices.length) {
|
||||
this.calculateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
Polygon.prototype.calculateProperties = function() {
|
||||
var _this = this;
|
||||
return returning(this, function() {
|
||||
var a, b, c, _ref;
|
||||
_ref = _this.vertices, a = _ref[0], b = _ref[1], c = _ref[2];
|
||||
_this.normal = b.clone().sub(a).cross(c.clone().sub(a)).normalize();
|
||||
return _this.w = _this.normal.clone().dot(a);
|
||||
});
|
||||
};
|
||||
|
||||
Polygon.prototype.clone = function() {
|
||||
var v;
|
||||
return new ThreeBSP.Polygon((function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = this.vertices;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
v = _ref[_i];
|
||||
_results.push(v.clone());
|
||||
}
|
||||
return _results;
|
||||
}).call(this), this.normal.clone(), this.w);
|
||||
};
|
||||
|
||||
Polygon.prototype.invert = function() {
|
||||
var _this = this;
|
||||
return returning(this, function() {
|
||||
_this.normal.multiplyScalar(-1);
|
||||
_this.w *= -1;
|
||||
return _this.vertices.reverse();
|
||||
});
|
||||
};
|
||||
|
||||
Polygon.prototype.classifyVertex = function(vertex) {
|
||||
var side;
|
||||
side = this.normal.dot(vertex) - this.w;
|
||||
switch (false) {
|
||||
case !(side < -EPSILON):
|
||||
return BACK;
|
||||
case !(side > EPSILON):
|
||||
return FRONT;
|
||||
default:
|
||||
return COPLANAR;
|
||||
}
|
||||
};
|
||||
|
||||
Polygon.prototype.classifySide = function(polygon) {
|
||||
var back, front, tally, v, _i, _len, _ref, _ref1,
|
||||
_this = this;
|
||||
_ref = [0, 0], front = _ref[0], back = _ref[1];
|
||||
tally = function(v) {
|
||||
switch (_this.classifyVertex(v)) {
|
||||
case FRONT:
|
||||
return front += 1;
|
||||
case BACK:
|
||||
return back += 1;
|
||||
}
|
||||
};
|
||||
_ref1 = polygon.vertices;
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
v = _ref1[_i];
|
||||
tally(v);
|
||||
}
|
||||
if (front > 0 && back === 0) {
|
||||
return FRONT;
|
||||
}
|
||||
if (front === 0 && back > 0) {
|
||||
return BACK;
|
||||
}
|
||||
if ((front === back && back === 0)) {
|
||||
return COPLANAR;
|
||||
}
|
||||
return SPANNING;
|
||||
};
|
||||
|
||||
Polygon.prototype.tessellate = function(poly) {
|
||||
var b, count, f, i, j, polys, t, ti, tj, v, vi, vj, _i, _len, _ref, _ref1, _ref2,
|
||||
_this = this;
|
||||
_ref = {
|
||||
f: [],
|
||||
b: [],
|
||||
count: poly.vertices.length
|
||||
}, f = _ref.f, b = _ref.b, count = _ref.count;
|
||||
if (this.classifySide(poly) !== SPANNING) {
|
||||
return [poly];
|
||||
}
|
||||
_ref1 = poly.vertices;
|
||||
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
|
||||
vi = _ref1[i];
|
||||
vj = poly.vertices[(j = (i + 1) % count)];
|
||||
_ref2 = (function() {
|
||||
var _j, _len1, _ref2, _results;
|
||||
_ref2 = [vi, vj];
|
||||
_results = [];
|
||||
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
||||
v = _ref2[_j];
|
||||
_results.push(this.classifyVertex(v));
|
||||
}
|
||||
return _results;
|
||||
}).call(this), ti = _ref2[0], tj = _ref2[1];
|
||||
if (ti !== BACK) {
|
||||
f.push(vi);
|
||||
}
|
||||
if (ti !== FRONT) {
|
||||
b.push(vi);
|
||||
}
|
||||
if ((ti | tj) === SPANNING) {
|
||||
t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().sub(vi));
|
||||
v = vi.interpolate(vj, t);
|
||||
f.push(v);
|
||||
b.push(v);
|
||||
}
|
||||
}
|
||||
return returning((polys = []), function() {
|
||||
if (f.length >= 3) {
|
||||
polys.push(new ThreeBSP.Polygon(f));
|
||||
}
|
||||
if (b.length >= 3) {
|
||||
return polys.push(new ThreeBSP.Polygon(b));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Polygon.prototype.subdivide = function(polygon, coplanar_front, coplanar_back, front, back) {
|
||||
var poly, side, _i, _len, _ref, _results;
|
||||
_ref = this.tessellate(polygon);
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
poly = _ref[_i];
|
||||
side = this.classifySide(poly);
|
||||
switch (side) {
|
||||
case FRONT:
|
||||
_results.push(front.push(poly));
|
||||
break;
|
||||
case BACK:
|
||||
_results.push(back.push(poly));
|
||||
break;
|
||||
case COPLANAR:
|
||||
if (this.normal.dot(poly.normal) > 0) {
|
||||
_results.push(coplanar_front.push(poly));
|
||||
} else {
|
||||
_results.push(coplanar_back.push(poly));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error("BUG: Polygon of classification " + side + " in subdivision");
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
return Polygon;
|
||||
|
||||
})();
|
||||
|
||||
ThreeBSP.Node = (function() {
|
||||
Node.prototype.clone = function() {
|
||||
var node,
|
||||
_this = this;
|
||||
return returning((node = new ThreeBSP.Node()), function() {
|
||||
var p, _ref, _ref1, _ref2;
|
||||
node.divider = (_ref = _this.divider) != null ? _ref.clone() : void 0;
|
||||
node.polygons = (function() {
|
||||
var _i, _len, _ref1, _results;
|
||||
_ref1 = this.polygons;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
p = _ref1[_i];
|
||||
_results.push(p.clone());
|
||||
}
|
||||
return _results;
|
||||
}).call(_this);
|
||||
node.front = (_ref1 = _this.front) != null ? _ref1.clone() : void 0;
|
||||
return node.back = (_ref2 = _this.back) != null ? _ref2.clone() : void 0;
|
||||
});
|
||||
};
|
||||
|
||||
function Node(polygons) {
|
||||
this.clipTo = __bind(this.clipTo, this);
|
||||
this.clipPolygons = __bind(this.clipPolygons, this);
|
||||
this.invert = __bind(this.invert, this);
|
||||
this.allPolygons = __bind(this.allPolygons, this);
|
||||
this.isConvex = __bind(this.isConvex, this);
|
||||
this.build = __bind(this.build, this);
|
||||
this.clone = __bind(this.clone, this);
|
||||
this.polygons = [];
|
||||
if ((polygons != null) && polygons.length) {
|
||||
this.build(polygons);
|
||||
}
|
||||
}
|
||||
|
||||
Node.prototype.build = function(polygons) {
|
||||
var _this = this;
|
||||
return returning(this, function() {
|
||||
var poly, polys, side, sides, _i, _len, _results;
|
||||
sides = {
|
||||
front: [],
|
||||
back: []
|
||||
};
|
||||
if (_this.divider == null) {
|
||||
_this.divider = polygons[0].clone();
|
||||
}
|
||||
for (_i = 0, _len = polygons.length; _i < _len; _i++) {
|
||||
poly = polygons[_i];
|
||||
_this.divider.subdivide(poly, _this.polygons, _this.polygons, sides.front, sides.back);
|
||||
}
|
||||
_results = [];
|
||||
for (side in sides) {
|
||||
if (!__hasProp.call(sides, side)) continue;
|
||||
polys = sides[side];
|
||||
if (polys.length) {
|
||||
if (_this[side] == null) {
|
||||
_this[side] = new ThreeBSP.Node();
|
||||
}
|
||||
_results.push(_this[side].build(polys));
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
};
|
||||
|
||||
Node.prototype.isConvex = function(polys) {
|
||||
var inner, outer, _i, _j, _len, _len1;
|
||||
for (_i = 0, _len = polys.length; _i < _len; _i++) {
|
||||
inner = polys[_i];
|
||||
for (_j = 0, _len1 = polys.length; _j < _len1; _j++) {
|
||||
outer = polys[_j];
|
||||
if (inner !== outer && outer.classifySide(inner) !== BACK) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
Node.prototype.allPolygons = function() {
|
||||
var _ref, _ref1;
|
||||
return this.polygons.slice().concat(((_ref1 = this.front) != null ? _ref1.allPolygons() : void 0) || []).concat(((_ref = this.back) != null ? _ref.allPolygons() : void 0) || []);
|
||||
};
|
||||
|
||||
Node.prototype.invert = function() {
|
||||
var _this = this;
|
||||
return returning(this, function() {
|
||||
var flipper, poly, _i, _j, _len, _len1, _ref, _ref1, _ref2;
|
||||
_ref = _this.polygons;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
poly = _ref[_i];
|
||||
poly.invert();
|
||||
}
|
||||
_ref1 = [_this.divider, _this.front, _this.back];
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
flipper = _ref1[_j];
|
||||
if (flipper != null) {
|
||||
flipper.invert();
|
||||
}
|
||||
}
|
||||
return _ref2 = [_this.back, _this.front], _this.front = _ref2[0], _this.back = _ref2[1], _ref2;
|
||||
});
|
||||
};
|
||||
|
||||
Node.prototype.clipPolygons = function(polygons) {
|
||||
var back, front, poly, _i, _len;
|
||||
if (!this.divider) {
|
||||
return polygons.slice();
|
||||
}
|
||||
front = [];
|
||||
back = [];
|
||||
for (_i = 0, _len = polygons.length; _i < _len; _i++) {
|
||||
poly = polygons[_i];
|
||||
this.divider.subdivide(poly, front, back, front, back);
|
||||
}
|
||||
if (this.front) {
|
||||
front = this.front.clipPolygons(front);
|
||||
}
|
||||
if (this.back) {
|
||||
back = this.back.clipPolygons(back);
|
||||
}
|
||||
return front.concat(this.back ? back : []);
|
||||
};
|
||||
|
||||
Node.prototype.clipTo = function(node) {
|
||||
var _this = this;
|
||||
return returning(this, function() {
|
||||
var _ref, _ref1;
|
||||
_this.polygons = node.clipPolygons(_this.polygons);
|
||||
if ((_ref = _this.front) != null) {
|
||||
_ref.clipTo(node);
|
||||
}
|
||||
return (_ref1 = _this.back) != null ? _ref1.clipTo(node) : void 0;
|
||||
});
|
||||
};
|
||||
|
||||
return Node;
|
||||
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* @author xiening
|
||||
* Running this will allow you to show white line around objects which you selected.
|
||||
*/
|
||||
/*
|
||||
* 需要在jsp中导入的包
|
||||
<script src="./ThreeJs/three.js"></script>
|
||||
<script src="./ThreeJs/EffectComposer.js"></script>
|
||||
<script src="./ThreeJs/RenderPass.js"></script>
|
||||
<script src="./ThreeJs/OutlinePass.js"></script>
|
||||
<script src="./ThreeJs/FXAAShader.js"></script>
|
||||
<script src="./ThreeJs/ShaderPass.js"></script>
|
||||
<script src="./ThreeJs/CopyShader.js"></script>
|
||||
*/
|
||||
|
||||
THREE.ThreeJs_Composer = function ( _renderer, _scene, _camera, _options, _selectobject) {
|
||||
var raycaster = new THREE.Raycaster();
|
||||
var mouse = new THREE.Vector2();
|
||||
var composer = new THREE.EffectComposer( _renderer );
|
||||
var renderPass = new THREE.RenderPass( _scene, _camera );
|
||||
var selectedObjects = [];
|
||||
composer.addPass( renderPass );
|
||||
var outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), _scene, _camera );
|
||||
outlinePass.edgeStrength = 5;//包围线浓度
|
||||
outlinePass.edgeGlow = 0.5;//边缘线范围
|
||||
outlinePass.edgeThickness = 2;//边缘线浓度
|
||||
outlinePass.pulsePeriod = 2;//包围线闪烁评率
|
||||
outlinePass.visibleEdgeColor.set( '#ffffff' );//包围线颜色
|
||||
outlinePass.hiddenEdgeColor.set( '#190a05' );//被遮挡的边界线颜色
|
||||
composer.addPass( outlinePass );
|
||||
var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
|
||||
effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
|
||||
effectFXAA.renderToScreen = true;
|
||||
// composer.addPass( effectFXAA );
|
||||
|
||||
window.addEventListener( 'click', onMouseClick);
|
||||
window.addEventListener( 'dblclick', onMouseDblClick);
|
||||
|
||||
var door_state_left1 = true; //默认是门是关闭的
|
||||
var door_state_right1 = true; //默认是门是关闭的
|
||||
function onMouseClick( event ) {
|
||||
var x, y;
|
||||
if ( event.changedTouches ) {
|
||||
x = event.changedTouches[ 0 ].pageX;
|
||||
y = event.changedTouches[ 0 ].pageY;
|
||||
} else {
|
||||
x = event.clientX;
|
||||
y = event.clientY;
|
||||
}
|
||||
mouse.x = ( x / window.innerWidth ) * 2 - 1;
|
||||
mouse.y = - ( y / window.innerHeight ) * 2 + 1;
|
||||
raycaster.setFromCamera( mouse, _camera );
|
||||
var intersects = raycaster.intersectObjects( [ _scene ], true );
|
||||
|
||||
if(intersects.length == 0){
|
||||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
||||
return;
|
||||
}
|
||||
if(intersects[0].object.name == "地面" || (intersects[0].object.name == "") || (intersects[0].object.name == "墙面")){
|
||||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
||||
selectedObjects.pop();
|
||||
}else{
|
||||
$("#label").attr("style","display:block;");// 显示说明性标签
|
||||
$("#label").css({left: x, top: y-40});// 修改标签的位置
|
||||
$("#label").text(intersects[0].object.name);// 显示模型信息
|
||||
|
||||
selectedObjects.pop();
|
||||
selectedObjects.push( intersects[0].object );
|
||||
outlinePass.selectedObjects = selectedObjects;//给选中的线条和物体加发光特效
|
||||
}
|
||||
|
||||
var Msg = intersects[0].object.name.split("$");
|
||||
if(Msg[0] == "货物") {
|
||||
_options.batchNo = "一个货物";
|
||||
_options.qty = "100";
|
||||
_options.qtyUom = "kg";
|
||||
_options.qty2 = "10";
|
||||
_options.selectObj = intersects[0].object.name;
|
||||
_selectobject.push( intersects[0].object );
|
||||
}
|
||||
|
||||
if(intersects[0].object.name == "左门1"){
|
||||
if(door_state_left1){
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: -0.5*Math.PI
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_left1 = false;
|
||||
}else{
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_left1 = true;
|
||||
}
|
||||
}else if(intersects[0].object.name == "右门1"){
|
||||
if(door_state_right1){
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0.5*Math.PI
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_right1 = false;
|
||||
}else{
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_right1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDblClick( event ) {
|
||||
var x, y;
|
||||
if ( event.changedTouches ) {
|
||||
x = event.changedTouches[ 0 ].pageX;
|
||||
y = event.changedTouches[ 0 ].pageY;
|
||||
} else {
|
||||
x = event.clientX;
|
||||
y = event.clientY;
|
||||
}
|
||||
mouse.x = ( x / window.innerWidth ) * 2 - 1;
|
||||
mouse.y = - ( y / window.innerHeight ) * 2 + 1;
|
||||
raycaster.setFromCamera( mouse, _camera );
|
||||
var intersects = raycaster.intersectObjects( [ _scene ], true );
|
||||
|
||||
if(intersects.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
var Msg = intersects[0].object.name.split("$");
|
||||
if(Msg[0] == "货物") {
|
||||
var href = "DispatchAction.do?efFormEname=YMIQ083DP&inqu_status-0-storageUnitId=" + Msg[1];
|
||||
EFColorbox({
|
||||
href : href,
|
||||
title:"货物详情",
|
||||
innerWidth:'1200px',
|
||||
innerHeight:'800px',
|
||||
iframe : true,
|
||||
scrolling : false,
|
||||
overlayClose: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return composer;
|
||||
}
|
||||
@@ -1,895 +0,0 @@
|
||||
/**
|
||||
* Tween.js - Licensed under the MIT license
|
||||
* https://github.com/tweenjs/tween.js
|
||||
* ----------------------------------------------
|
||||
*
|
||||
* See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
|
||||
* Thank you all, you're awesome!
|
||||
*/
|
||||
|
||||
var TWEEN = TWEEN || (function () {
|
||||
|
||||
var _tweens = [];
|
||||
|
||||
return {
|
||||
|
||||
getAll: function () {
|
||||
|
||||
return _tweens;
|
||||
|
||||
},
|
||||
|
||||
removeAll: function () {
|
||||
|
||||
_tweens = [];
|
||||
|
||||
},
|
||||
|
||||
add: function (tween) {
|
||||
|
||||
_tweens.push(tween);
|
||||
|
||||
},
|
||||
|
||||
remove: function (tween) {
|
||||
|
||||
var i = _tweens.indexOf(tween);
|
||||
|
||||
if (i !== -1) {
|
||||
_tweens.splice(i, 1);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
update: function (time, preserve) {
|
||||
|
||||
if (_tweens.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
time = time !== undefined ? time : TWEEN.now();
|
||||
|
||||
while (i < _tweens.length) {
|
||||
|
||||
if (_tweens[i].update(time) || preserve) {
|
||||
i++;
|
||||
} else {
|
||||
_tweens.splice(i, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
|
||||
// Include a performance.now polyfill.
|
||||
// In node.js, use process.hrtime.
|
||||
if (typeof (window) === 'undefined' && typeof (process) !== 'undefined') {
|
||||
TWEEN.now = function () {
|
||||
var time = process.hrtime();
|
||||
|
||||
// Convert [seconds, nanoseconds] to milliseconds.
|
||||
return time[0] * 1000 + time[1] / 1000000;
|
||||
};
|
||||
}
|
||||
// In a browser, use window.performance.now if it is available.
|
||||
else if (typeof (window) !== 'undefined' &&
|
||||
window.performance !== undefined &&
|
||||
window.performance.now !== undefined) {
|
||||
// This must be bound, because directly assigning this function
|
||||
// leads to an invocation exception in Chrome.
|
||||
TWEEN.now = window.performance.now.bind(window.performance);
|
||||
}
|
||||
// Use Date.now if it is available.
|
||||
else if (Date.now !== undefined) {
|
||||
TWEEN.now = Date.now;
|
||||
}
|
||||
// Otherwise, use 'new Date().getTime()'.
|
||||
else {
|
||||
TWEEN.now = function () {
|
||||
return new Date().getTime();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function assign(target, source) {
|
||||
var keys = Object.keys(source);
|
||||
var length = keys.length;
|
||||
|
||||
for (var i = 0; i < length; i += 1) {
|
||||
target[keys[i]] = source[keys[i]];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
TWEEN.Tween = function (object) {
|
||||
|
||||
this._object = object;
|
||||
this._valuesStart = {};
|
||||
this._valuesEnd = {};
|
||||
this._valuesStartRepeat = {};
|
||||
this._duration = 1000;
|
||||
this._repeat = 0;
|
||||
this._repeatDelayTime = undefined;
|
||||
this._yoyo = false;
|
||||
this._isPlaying = false;
|
||||
this._reversed = false;
|
||||
this._delayTime = 0;
|
||||
this._startTime = null;
|
||||
this._easingFunction = TWEEN.Easing.Linear.None;
|
||||
this._interpolationFunction = TWEEN.Interpolation.Linear;
|
||||
this._chainedTweens = [];
|
||||
this._onStartCallback = null;
|
||||
this._onStartCallbackFired = false;
|
||||
this._onUpdateCallback = null;
|
||||
this._onCompleteCallback = null;
|
||||
this._onStopCallback = null;
|
||||
|
||||
};
|
||||
|
||||
TWEEN.Tween.prototype = assign(Object.create(Object.prototype), {
|
||||
to: function to(properties, duration) {
|
||||
|
||||
this._valuesEnd = properties;
|
||||
|
||||
if (duration !== undefined) {
|
||||
this._duration = duration;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
start: function start(time) {
|
||||
|
||||
TWEEN.add(this);
|
||||
|
||||
this._isPlaying = true;
|
||||
|
||||
this._onStartCallbackFired = false;
|
||||
|
||||
this._startTime = time !== undefined ? time : TWEEN.now();
|
||||
this._startTime += this._delayTime;
|
||||
|
||||
for (var property in this._valuesEnd) {
|
||||
|
||||
// Check if an Array was provided as property value
|
||||
if (this._valuesEnd[property] instanceof Array) {
|
||||
|
||||
if (this._valuesEnd[property].length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a local copy of the Array with the start value at the front
|
||||
this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]);
|
||||
|
||||
}
|
||||
|
||||
// If `to()` specifies a property that doesn't exist in the source object,
|
||||
// we should not set that property in the object
|
||||
if (this._object[property] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Save the starting value.
|
||||
this._valuesStart[property] = this._object[property];
|
||||
|
||||
if ((this._valuesStart[property] instanceof Array) === false) {
|
||||
this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
|
||||
}
|
||||
|
||||
this._valuesStartRepeat[property] = this._valuesStart[property] || 0;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
stop: function stop() {
|
||||
|
||||
if (!this._isPlaying) {
|
||||
return this;
|
||||
}
|
||||
|
||||
TWEEN.remove(this);
|
||||
this._isPlaying = false;
|
||||
|
||||
if (this._onStopCallback !== null) {
|
||||
this._onStopCallback.call(this._object, this._object);
|
||||
}
|
||||
|
||||
this.stopChainedTweens();
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
end: function end() {
|
||||
|
||||
this.update(this._startTime + this._duration);
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
stopChainedTweens: function stopChainedTweens() {
|
||||
|
||||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
|
||||
this._chainedTweens[i].stop();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
delay: function delay(amount) {
|
||||
|
||||
this._delayTime = amount;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
repeat: function repeat(times) {
|
||||
|
||||
this._repeat = times;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
repeatDelay: function repeatDelay(amount) {
|
||||
|
||||
this._repeatDelayTime = amount;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
yoyo: function yoyo(yoyo) {
|
||||
|
||||
this._yoyo = yoyo;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
easing: function easing(easing) {
|
||||
|
||||
this._easingFunction = easing;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
interpolation: function interpolation(interpolation) {
|
||||
|
||||
this._interpolationFunction = interpolation;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
chain: function chain() {
|
||||
|
||||
this._chainedTweens = arguments;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
onStart: function onStart(callback) {
|
||||
|
||||
this._onStartCallback = callback;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
onUpdate: function onUpdate(callback) {
|
||||
|
||||
this._onUpdateCallback = callback;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
onComplete: function onComplete(callback) {
|
||||
|
||||
this._onCompleteCallback = callback;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
onStop: function onStop(callback) {
|
||||
|
||||
this._onStopCallback = callback;
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
update: function update(time) {
|
||||
|
||||
var property;
|
||||
var elapsed;
|
||||
var value;
|
||||
|
||||
if (time < this._startTime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this._onStartCallbackFired === false) {
|
||||
|
||||
if (this._onStartCallback !== null) {
|
||||
this._onStartCallback.call(this._object, this._object);
|
||||
}
|
||||
|
||||
this._onStartCallbackFired = true;
|
||||
}
|
||||
|
||||
elapsed = (time - this._startTime) / this._duration;
|
||||
elapsed = elapsed > 1 ? 1 : elapsed;
|
||||
|
||||
value = this._easingFunction(elapsed);
|
||||
|
||||
for (property in this._valuesEnd) {
|
||||
|
||||
// Don't update properties that do not exist in the source object
|
||||
if (this._valuesStart[property] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var start = this._valuesStart[property] || 0;
|
||||
var end = this._valuesEnd[property];
|
||||
|
||||
if (end instanceof Array) {
|
||||
|
||||
this._object[property] = this._interpolationFunction(end, value);
|
||||
|
||||
} else {
|
||||
|
||||
// Parses relative end values with start as base (e.g.: +10, -3)
|
||||
if (typeof (end) === 'string') {
|
||||
|
||||
if (end.charAt(0) === '+' || end.charAt(0) === '-') {
|
||||
end = start + parseFloat(end);
|
||||
} else {
|
||||
end = parseFloat(end);
|
||||
}
|
||||
}
|
||||
|
||||
// Protect against non numeric properties.
|
||||
if (typeof (end) === 'number') {
|
||||
this._object[property] = start + (end - start) * value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (this._onUpdateCallback !== null) {
|
||||
this._onUpdateCallback.call(this._object, value);
|
||||
}
|
||||
|
||||
if (elapsed === 1) {
|
||||
|
||||
if (this._repeat > 0) {
|
||||
|
||||
if (isFinite(this._repeat)) {
|
||||
this._repeat--;
|
||||
}
|
||||
|
||||
// Reassign starting values, restart by making startTime = now
|
||||
for (property in this._valuesStartRepeat) {
|
||||
|
||||
if (typeof (this._valuesEnd[property]) === 'string') {
|
||||
this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]);
|
||||
}
|
||||
|
||||
if (this._yoyo) {
|
||||
var tmp = this._valuesStartRepeat[property];
|
||||
|
||||
this._valuesStartRepeat[property] = this._valuesEnd[property];
|
||||
this._valuesEnd[property] = tmp;
|
||||
}
|
||||
|
||||
this._valuesStart[property] = this._valuesStartRepeat[property];
|
||||
|
||||
}
|
||||
|
||||
if (this._yoyo) {
|
||||
this._reversed = !this._reversed;
|
||||
}
|
||||
|
||||
if (this._repeatDelayTime !== undefined) {
|
||||
this._startTime = time + this._repeatDelayTime;
|
||||
} else {
|
||||
this._startTime = time + this._delayTime;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
if (this._onCompleteCallback !== null) {
|
||||
|
||||
this._onCompleteCallback.call(this._object, this._object);
|
||||
}
|
||||
|
||||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) {
|
||||
// Make the chained tweens start exactly at the time they should,
|
||||
// even if the `update()` method was called way past the duration of the tween
|
||||
this._chainedTweens[i].start(this._startTime + this._duration);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
TWEEN.Easing = {
|
||||
|
||||
Linear: {
|
||||
|
||||
None: function (k) {
|
||||
|
||||
return k;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Quadratic: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return k * k;
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return k * (2 - k);
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * k * k;
|
||||
}
|
||||
|
||||
return - 0.5 * (--k * (k - 2) - 1);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Cubic: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return k * k * k;
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return --k * k * k + 1;
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * k * k * k;
|
||||
}
|
||||
|
||||
return 0.5 * ((k -= 2) * k * k + 2);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Quartic: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return k * k * k * k;
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return 1 - (--k * k * k * k);
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * k * k * k * k;
|
||||
}
|
||||
|
||||
return - 0.5 * ((k -= 2) * k * k * k - 2);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Quintic: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return k * k * k * k * k;
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return --k * k * k * k * k + 1;
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * k * k * k * k * k;
|
||||
}
|
||||
|
||||
return 0.5 * ((k -= 2) * k * k * k * k + 2);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Sinusoidal: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return 1 - Math.cos(k * Math.PI / 2);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return Math.sin(k * Math.PI / 2);
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
return 0.5 * (1 - Math.cos(Math.PI * k));
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Exponential: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return k === 0 ? 0 : Math.pow(1024, k - 1);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k);
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if (k === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k === 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * Math.pow(1024, k - 1);
|
||||
}
|
||||
|
||||
return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Circular: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return 1 - Math.sqrt(1 - k * k);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
return Math.sqrt(1 - (--k * k));
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return - 0.5 * (Math.sqrt(1 - k * k) - 1);
|
||||
}
|
||||
|
||||
return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Elastic: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
if (k === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k === 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
if (k === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k === 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if (k === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k === 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
k *= 2;
|
||||
|
||||
if (k < 1) {
|
||||
return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
|
||||
}
|
||||
|
||||
return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Back: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
var s = 1.70158;
|
||||
|
||||
return k * k * ((s + 1) * k - s);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
var s = 1.70158;
|
||||
|
||||
return --k * k * ((s + 1) * k + s) + 1;
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
var s = 1.70158 * 1.525;
|
||||
|
||||
if ((k *= 2) < 1) {
|
||||
return 0.5 * (k * k * ((s + 1) * k - s));
|
||||
}
|
||||
|
||||
return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Bounce: {
|
||||
|
||||
In: function (k) {
|
||||
|
||||
return 1 - TWEEN.Easing.Bounce.Out(1 - k);
|
||||
|
||||
},
|
||||
|
||||
Out: function (k) {
|
||||
|
||||
if (k < (1 / 2.75)) {
|
||||
return 7.5625 * k * k;
|
||||
} else if (k < (2 / 2.75)) {
|
||||
return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
|
||||
} else if (k < (2.5 / 2.75)) {
|
||||
return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
|
||||
} else {
|
||||
return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
InOut: function (k) {
|
||||
|
||||
if (k < 0.5) {
|
||||
return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
|
||||
}
|
||||
|
||||
return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TWEEN.Interpolation = {
|
||||
|
||||
Linear: function (v, k) {
|
||||
|
||||
var m = v.length - 1;
|
||||
var f = m * k;
|
||||
var i = Math.floor(f);
|
||||
var fn = TWEEN.Interpolation.Utils.Linear;
|
||||
|
||||
if (k < 0) {
|
||||
return fn(v[0], v[1], f);
|
||||
}
|
||||
|
||||
if (k > 1) {
|
||||
return fn(v[m], v[m - 1], m - f);
|
||||
}
|
||||
|
||||
return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
|
||||
|
||||
},
|
||||
|
||||
Bezier: function (v, k) {
|
||||
|
||||
var b = 0;
|
||||
var n = v.length - 1;
|
||||
var pw = Math.pow;
|
||||
var bn = TWEEN.Interpolation.Utils.Bernstein;
|
||||
|
||||
for (var i = 0; i <= n; i++) {
|
||||
b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
|
||||
}
|
||||
|
||||
return b;
|
||||
|
||||
},
|
||||
|
||||
CatmullRom: function (v, k) {
|
||||
|
||||
var m = v.length - 1;
|
||||
var f = m * k;
|
||||
var i = Math.floor(f);
|
||||
var fn = TWEEN.Interpolation.Utils.CatmullRom;
|
||||
|
||||
if (v[0] === v[m]) {
|
||||
|
||||
if (k < 0) {
|
||||
i = Math.floor(f = m * (1 + k));
|
||||
}
|
||||
|
||||
return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
|
||||
|
||||
} else {
|
||||
|
||||
if (k < 0) {
|
||||
return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
|
||||
}
|
||||
|
||||
if (k > 1) {
|
||||
return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
|
||||
}
|
||||
|
||||
return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
Utils: {
|
||||
|
||||
Linear: function (p0, p1, t) {
|
||||
|
||||
return (p1 - p0) * t + p0;
|
||||
|
||||
},
|
||||
|
||||
Bernstein: function (n, i) {
|
||||
|
||||
var fc = TWEEN.Interpolation.Utils.Factorial;
|
||||
|
||||
return fc(n) / fc(i) / fc(n - i);
|
||||
|
||||
},
|
||||
|
||||
Factorial: (function () {
|
||||
|
||||
var a = [1];
|
||||
|
||||
return function (n) {
|
||||
|
||||
var s = 1;
|
||||
|
||||
if (a[n]) {
|
||||
return a[n];
|
||||
}
|
||||
|
||||
for (var i = n; i > 1; i--) {
|
||||
s *= i;
|
||||
}
|
||||
|
||||
a[n] = s;
|
||||
return s;
|
||||
|
||||
};
|
||||
|
||||
})(),
|
||||
|
||||
CatmullRom: function (p0, p1, p2, p3, t) {
|
||||
|
||||
var v0 = (p2 - p0) * 0.5;
|
||||
var v1 = (p3 - p1) * 0.5;
|
||||
var t2 = t * t;
|
||||
var t3 = t * t2;
|
||||
|
||||
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// UMD (Universal Module Definition)
|
||||
(function (root) {
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
|
||||
// AMD
|
||||
define([], function () {
|
||||
return TWEEN;
|
||||
});
|
||||
|
||||
} else if (typeof module !== 'undefined' && typeof exports === 'object') {
|
||||
|
||||
// Node.js
|
||||
module.exports = TWEEN;
|
||||
|
||||
} else if (root !== undefined) {
|
||||
|
||||
// Global variable
|
||||
root.TWEEN = TWEEN;
|
||||
|
||||
}
|
||||
|
||||
})(this);
|
||||
14
src/main/webapp/house/dat.gui.min.js
vendored
|
Before Width: | Height: | Size: 112 KiB |
4
src/main/webapp/house/jquery-1.11.0.min.js
vendored
5
src/main/webapp/house/stats.min.js
vendored
@@ -1,5 +0,0 @@
|
||||
// stats.js - http://github.com/mrdoob/stats.js
|
||||
var Stats=function(){function h(a){c.appendChild(a.dom);return a}function k(a){for(var d=0;d<c.children.length;d++)c.children[d].style.display=d===a?"block":"none";l=a}var l=0,c=document.createElement("div");c.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";c.addEventListener("click",function(a){a.preventDefault();k(++l%c.children.length)},!1);var g=(performance||Date).now(),e=g,a=0,r=h(new Stats.Panel("FPS","#0ff","#002")),f=h(new Stats.Panel("MS","#0f0","#020"));
|
||||
if(self.performance&&self.performance.memory)var t=h(new Stats.Panel("MB","#f08","#201"));k(0);return{REVISION:16,dom:c,addPanel:h,showPanel:k,begin:function(){g=(performance||Date).now()},end:function(){a++;var c=(performance||Date).now();f.update(c-g,200);if(c>e+1E3&&(r.update(1E3*a/(c-e),100),e=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){g=this.end()},domElement:c,setMode:k}};
|
||||
Stats.Panel=function(h,k,l){var c=Infinity,g=0,e=Math.round,a=e(window.devicePixelRatio||1),r=80*a,f=48*a,t=3*a,u=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=f;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,f);b.fillStyle=k;b.fillText(h,t,u);b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(f,
|
||||
v){c=Math.min(c,f);g=Math.max(g,f);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=k;b.fillText(e(f)+" "+h+" ("+e(c)+"-"+e(g)+")",t,u);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,e((1-f/v)*p))}}};"object"===typeof module&&(module.exports=Stats);
|
||||
@@ -1,84 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title></title>
|
||||
<style type="text/css">
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.Bigbox {
|
||||
width: 70%;
|
||||
margin: 0 auto;
|
||||
background: #efefef;
|
||||
text-align: center;
|
||||
padding: 150px 100px;
|
||||
}
|
||||
|
||||
.top {
|
||||
height: 20px;
|
||||
/* border: 1px solid red; */
|
||||
transform: translateX(30px) skewX(-70deg);
|
||||
/* background: #00ffff; */
|
||||
width: 300px;
|
||||
border: 1px solid yellow;
|
||||
display: flex;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.topchild {
|
||||
flex: 1;
|
||||
border-right: 8px solid yellow;
|
||||
border-left: 8px solid yellow;
|
||||
/* background: red; */
|
||||
}
|
||||
|
||||
.fa {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.box {
|
||||
height: 300px;
|
||||
border: 1px solid yellow;
|
||||
width: 300px;
|
||||
/* background: red; */
|
||||
}
|
||||
|
||||
.right {
|
||||
height: 300px;
|
||||
border: 1px solid yellow;
|
||||
width: 60px;
|
||||
/* background:/* #FF0000; */
|
||||
*/ border-radius: 5px;
|
||||
transform: translateY(-10px) skewY(-20deg);
|
||||
/* transform: ; */
|
||||
}
|
||||
|
||||
.rightchild {
|
||||
height: 100px;
|
||||
border: 1px solid yellow;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="Bigbox">
|
||||
<div class="top">
|
||||
<div class="topchild"></div>
|
||||
<div class="topchild"></div>
|
||||
<div class="topchild"></div>
|
||||
</div>
|
||||
<div class="fa">
|
||||
<div class="box"></div>
|
||||
<div class="right">
|
||||
<div class="rightchild"></div>
|
||||
<div class="rightchild"></div>
|
||||
<div class="rightchild"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,387 +0,0 @@
|
||||
/**
|
||||
* Modules.js是3D库区图显示模型存放的地方
|
||||
*
|
||||
* @author 谢宁, Created on 2018-06-07
|
||||
*/
|
||||
/** ***************************************************************** */
|
||||
//模型材质信息
|
||||
var planeMat, RackMat, RackMat2, CargoMat, LineMat, RollTexture, RollMat;
|
||||
//库区信息
|
||||
var storageZoneSize = 0, storageZoneList = [];
|
||||
//货架信息
|
||||
var shelfSize = 0, shelfList = [];
|
||||
//货位信息
|
||||
var storageUnitSize = 0, storageUnitList = [];
|
||||
//货物信息
|
||||
var cargoSize = 0, cargoList = [], CargosExist;
|
||||
|
||||
//创建库区对象
|
||||
function storageZone(StorageZoneId,StorageZoneName,
|
||||
coordinateX,coordinateZ,
|
||||
width,length,
|
||||
textColor,fontSize,textposition)
|
||||
{
|
||||
this.StorageZoneId=StorageZoneId;
|
||||
this.StorageZoneName=StorageZoneName;
|
||||
this.coordinateX=coordinateX;
|
||||
this.coordinateZ=coordinateZ;
|
||||
this.width=width;
|
||||
this.length=length;
|
||||
this.textColor=textColor;
|
||||
this.fontSize=fontSize;
|
||||
this.textposition=textposition;
|
||||
}
|
||||
|
||||
//根据库区编码获取库区对象
|
||||
function getStorageZoneById(StorageZoneId) {
|
||||
for(var i = 0; i < storageZoneSize; i++){
|
||||
if(storageZoneList[i].StorageZoneId == StorageZoneId){
|
||||
return storageZoneList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//创建货架对象
|
||||
function shelf(storageZoneId, shelfId, shelfName,
|
||||
planeLength , planeWidth , planeHeight ,
|
||||
holderLength , holderWidth , holderHeight ,
|
||||
positionX , positionY , positionZ ,
|
||||
layerNum , columnNum)
|
||||
{
|
||||
this.storageZoneId=storageZoneId;
|
||||
this.shelfId=shelfId;
|
||||
this.shelfName=shelfName;
|
||||
this.planeLength=planeLength;
|
||||
this.planeWidth=planeWidth;
|
||||
this.planeHeight=planeHeight;
|
||||
this.holderLength=holderLength;
|
||||
this.holderWidth=holderWidth;
|
||||
this.holderHeight=holderHeight;
|
||||
this.positionX=positionX;
|
||||
this.positionY=positionY;
|
||||
this.positionZ=positionZ;
|
||||
this.layerNum=layerNum;
|
||||
this.columnNum=columnNum;
|
||||
}
|
||||
|
||||
//根据货架编码获取货架对象
|
||||
function getShelfById(shelfId) {
|
||||
for(var i = 0; i < shelfSize; i++){
|
||||
if(shelfList[i].shelfId == shelfId){
|
||||
return shelfList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//创建货位对象
|
||||
function storageUnit(storageZoneId, shelfId, shelfName,
|
||||
inLayerNum , inColumnNum ,
|
||||
positionX , positionY , positionZ, storageUnitId)
|
||||
{
|
||||
this.storageZoneId=storageZoneId;
|
||||
this.shelfId=shelfId;
|
||||
this.shelfName=shelfName;
|
||||
this.inLayerNum=inLayerNum;
|
||||
this.inColumnNum=inColumnNum;
|
||||
this.positionX=positionX;
|
||||
this.positionY=positionY;
|
||||
this.positionZ=positionZ;
|
||||
this.storageUnitId=storageUnitId;
|
||||
}
|
||||
|
||||
//根据货架ID、层数、列数获取货位对象
|
||||
function getStorageUnitById(shelfId,inLayerNum,inColumnNum) {
|
||||
for(var i = 0; i < storageUnitSize; i++){
|
||||
if(storageUnitList[i].shelfId == shelfId && storageUnitList[i].inLayerNum == inLayerNum && storageUnitList[i].inColumnNum == inColumnNum){
|
||||
return storageUnitList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//根据库位编码获取货位对象
|
||||
function getStorageUnitByUnitId(storageUnitId) {
|
||||
for(var i = 0; i < storageUnitSize; i++){
|
||||
if(storageUnitList[i].storageUnitId == storageUnitId){
|
||||
return storageUnitList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//创建货物对象
|
||||
function cargo(batchNo, prodBatchNo, inBatchNo,
|
||||
matId, matClassId, matName,
|
||||
qty, qtyUom, qty2,
|
||||
warehouseId, storageZoneId, storageUnitId,
|
||||
positionX , positionY , positionZ,
|
||||
length , width , height)
|
||||
{
|
||||
this.batchNo=batchNo;
|
||||
this.prodBatchNo=prodBatchNo;
|
||||
this.inBatchNo=inBatchNo;
|
||||
this.matId=matId;
|
||||
this.matClassId=matClassId;
|
||||
this.matName=matName;
|
||||
this.qtyUom=qtyUom;
|
||||
this.qty2=qty2;
|
||||
this.warehouseId=warehouseId;
|
||||
this.storageZoneId=storageZoneId;
|
||||
this.storageUnitId=storageUnitId;
|
||||
this.positionX=positionX;
|
||||
this.positionY=positionY;
|
||||
this.positionZ=positionZ;
|
||||
this.length=length;
|
||||
this.width=width;
|
||||
this.height=height;
|
||||
}
|
||||
|
||||
/** 初始化材质信息 */
|
||||
function initMat() {
|
||||
planeMat = new THREE.MeshLambertMaterial();
|
||||
RackMat = new THREE.MeshLambertMaterial();
|
||||
RackMat2 = new THREE.MeshPhongMaterial({color:0x1C86EE});
|
||||
CargoMat = new THREE.MeshLambertMaterial();
|
||||
LineMat = new THREE.MeshLambertMaterial();
|
||||
RollMat = new THREE.MeshLambertMaterial();
|
||||
|
||||
new THREE.TextureLoader().load( './ThreeJs/images/plane.png', function( map ) {
|
||||
planeMat.map = map;
|
||||
planeMat.transparent = true;
|
||||
planeMat.opacity = 0.8;
|
||||
planeMat.needsUpdate = true;
|
||||
} );
|
||||
new THREE.TextureLoader().load( "./ThreeJs/images/rack.png", function( map ) {
|
||||
RackMat.map = map;
|
||||
RackMat.needsUpdate = true;
|
||||
} );
|
||||
new THREE.TextureLoader().load( "./ThreeJs/images/box.png", function( map ) {
|
||||
CargoMat.map = map;
|
||||
CargoMat.needsUpdate = true;
|
||||
} );
|
||||
new THREE.TextureLoader().load( "./ThreeJs/images/line.png", function( map ) {
|
||||
LineMat.map = map;
|
||||
LineMat.needsUpdate = true;
|
||||
} );
|
||||
RollTexture = new THREE.TextureLoader().load( "./ThreeJs/images/biaoyu.png", function( map ) {
|
||||
RollMat.map = map;
|
||||
RollMat.needsUpdate = true;
|
||||
RollMat.transparent = true;
|
||||
RollMat.side = THREE.DoubleSide;
|
||||
} );
|
||||
RollTexture.wrapS = THREE.RepeatWrapping;
|
||||
RollTexture.wrapT=THREE.RepeatWrapping;
|
||||
}
|
||||
|
||||
//region 放置天空盒
|
||||
function addSkybox( size,scene ) {
|
||||
urls = [
|
||||
'./ThreeJs/images/skybox/远山_RT.jpg', // right
|
||||
'./ThreeJs/images/skybox/远山_LF.jpg', // left
|
||||
'./ThreeJs/images/skybox/远山_UP.jpg', // top
|
||||
'./ThreeJs/images/skybox/远山_DN.jpg', // bottom
|
||||
'./ThreeJs/images/skybox/远山_BK.jpg', // back
|
||||
'./ThreeJs/images/skybox/远山_FR.jpg' // front
|
||||
];
|
||||
var skyboxCubemap = new THREE.CubeTextureLoader().load( urls );
|
||||
skyboxCubemap.format = THREE.RGBFormat;
|
||||
|
||||
var skyboxShader = THREE.ShaderLib['cube'];
|
||||
skyboxShader.uniforms['tCube'].value = skyboxCubemap;
|
||||
var obj = new THREE.Mesh(
|
||||
new THREE.BoxGeometry( size, size, size ),
|
||||
new THREE.ShaderMaterial({
|
||||
fragmentShader : skyboxShader.fragmentShader,
|
||||
vertexShader : skyboxShader.vertexShader,
|
||||
uniforms : skyboxShader.uniforms,
|
||||
depthWrite : false,
|
||||
side : THREE.BackSide
|
||||
})
|
||||
);
|
||||
scene.add( obj );
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region 滚动的物体
|
||||
function addRollPlane(scene) {
|
||||
var geometry = new THREE.PlaneGeometry( 400, 20 );
|
||||
var obj = new THREE.Mesh( geometry, RollMat );
|
||||
obj.position.set(0,150,-690);
|
||||
scene.add( obj );
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region 放置视频面板
|
||||
function addVideoPlane( x,y,z,width,length,scene,videoId ) {
|
||||
var planeGeometry = new THREE.PlaneGeometry(width, length);
|
||||
var material = new THREE.MeshPhongMaterial();
|
||||
material.side = THREE.DoubleSide;
|
||||
var video = document.getElementById(videoId);
|
||||
var texture = new THREE.VideoTexture(video);
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.format = THREE.RGBFormat;
|
||||
material.map = texture;
|
||||
var mesh = new THREE.Mesh(planeGeometry, material);
|
||||
mesh.position.set(x,y,z);
|
||||
scene.add(mesh);
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region 矩形区域
|
||||
function addPlane(x,z,width,length,scene) {
|
||||
var lineWidth = 8
|
||||
var geometry = new THREE.PlaneGeometry( lineWidth, length );
|
||||
var obj = new THREE.Mesh( geometry, LineMat );
|
||||
obj.position.set(x,1.5,z);
|
||||
obj.rotation.x = -Math.PI / 2.0;
|
||||
var obj2 = obj.clone();
|
||||
obj2.translateX(width);
|
||||
|
||||
var geometry2 = new THREE.PlaneGeometry( lineWidth, width );
|
||||
var obj3 = new THREE.Mesh( geometry2, LineMat );
|
||||
obj3.position.set(x+width/2,1.5,z-length/2+lineWidth/2);
|
||||
obj3.rotation.x = -Math.PI / 2.0;
|
||||
obj3.rotation.z = -Math.PI / 2.0;
|
||||
var obj4 = obj3.clone();
|
||||
obj4.translateX(length-lineWidth);
|
||||
|
||||
var group = new THREE.Group();
|
||||
group.add(obj);
|
||||
group.add(obj2);
|
||||
group.add(obj3);
|
||||
group.add(obj4);
|
||||
group.translateX(-width/2);
|
||||
scene.add( group );
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region 库区
|
||||
/** 放置虚线框区域和库区名称 */
|
||||
function addArea(x,z,width,length,scene,name,textColor,font_size,textposition) {
|
||||
addPlane(x,z,width,length,scene);
|
||||
|
||||
new THREE.FontLoader().load('./ThreeJs/FZYaoTi_Regular.json',function(font){
|
||||
////加入立体文字
|
||||
var text= new THREE.TextGeometry(name.split("$")[1],{
|
||||
// 设定文字字体
|
||||
font:font,
|
||||
//尺寸
|
||||
size:font_size,
|
||||
//厚度
|
||||
height:0.01
|
||||
});
|
||||
text.computeBoundingBox();
|
||||
//3D文字材质
|
||||
var m = new THREE.MeshStandardMaterial({color:"#" + textColor});
|
||||
var mesh = new THREE.Mesh(text,m)
|
||||
if(textposition == "左对齐"){
|
||||
mesh.position.x = x - width/2 + 10;
|
||||
}else if(textposition == "居中"){
|
||||
mesh.position.x = x - 15;
|
||||
}else if(textposition == "右对齐"){
|
||||
mesh.position.x = x + width/2 - 60;
|
||||
}
|
||||
mesh.position.y = 1.3;
|
||||
mesh.position.z = z + length/2 - 20;
|
||||
mesh.rotation.x = -Math.PI / 2.0;
|
||||
scene.add(mesh);
|
||||
});
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region 货架货位
|
||||
|
||||
/** 放置单层货架 */
|
||||
/** x,y,z 整个模型在场景中的位置 */
|
||||
/** plane_x,plane_y,plane_z 货架板面的长高宽 */
|
||||
/** holder_x,holder_y,holder_z 货架支架的长高宽 */
|
||||
/** scene,name,num 要添加的场景,货架的名字,单层货架的库位数量 */
|
||||
function addRack(x,y,z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name,num) {
|
||||
var plane = new THREE.BoxGeometry( plane_x, plane_y, plane_z/num );
|
||||
var gz = [];
|
||||
for(var i = 0; i < num; i++){
|
||||
gz.push( z + plane_z/num/2 + (plane_z/num)*i );
|
||||
var obj = new THREE.Mesh( plane, RackMat );
|
||||
obj.position.set(x , y, gz[i]) ;
|
||||
var msg = name+"$"+(GET_COLUMN_NUM() - i);
|
||||
|
||||
var storageUnitId = msg.split("$")[1] + "$" + msg.split("$")[3] + "$" + msg.split("$")[4];
|
||||
|
||||
//添加货位
|
||||
var storageUnit_obj = new storageUnit(msg.split("$")[0],
|
||||
msg.split("$")[1],
|
||||
msg.split("$")[2],
|
||||
msg.split("$")[3],
|
||||
msg.split("$")[4],
|
||||
x, y, gz[i], storageUnitId);
|
||||
storageUnitList.push(storageUnit_obj);
|
||||
storageUnitSize++;
|
||||
|
||||
var Unit = getStorageUnitById(msg.split("$")[1],msg.split("$")[3],msg.split("$")[4]);
|
||||
obj.name = "货位"+"$"+Unit.storageUnitId;
|
||||
scene.add(obj);
|
||||
}
|
||||
|
||||
var holder = new THREE.BoxGeometry( holder_x, holder_y, holder_z );
|
||||
var obj2 = new THREE.Mesh( holder, RackMat2, 0 );
|
||||
var obj3 = new THREE.Mesh( holder, RackMat2, 0 );
|
||||
var obj4 = new THREE.Mesh( holder, RackMat2, 0 );
|
||||
var obj5 = new THREE.Mesh( holder, RackMat2, 0 );
|
||||
|
||||
obj2.position.set(x-plane_x/2+holder_x/2,y-holder_y/2-plane_y/2,z+holder_z/2);
|
||||
obj3.position.set(x+plane_x/2-holder_x/2,y-holder_y/2-plane_y/2,z+holder_z/2);
|
||||
obj4.position.set(x-plane_x/2+holder_x/2,y-holder_y/2-plane_y/2,z+plane_z-holder_z/2);
|
||||
obj5.position.set(x+plane_x/2-holder_x/2,y-holder_y/2-plane_y/2,z+plane_z-holder_z/2);
|
||||
scene.add(obj2);scene.add(obj3);scene.add(obj4);scene.add(obj5);
|
||||
}
|
||||
|
||||
/** 放置一叠货架 */
|
||||
/** stack_num 货架的叠数 */
|
||||
function addStackOfRack(x,y,z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name,num,stack_num) {
|
||||
for(var i = 0; i < stack_num; i++){
|
||||
addRack(x,y*(i+1),z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name+"$"+(i+1),num);
|
||||
}
|
||||
}
|
||||
|
||||
/** 根据3D库图货架配置表添加货架 */
|
||||
function addShelf(scene) {
|
||||
var shelf_list = GET_SHELF_LIST();
|
||||
shelfSize = shelf_list.length;
|
||||
for(var i = 0; i < shelfSize; i++){
|
||||
var shelf_obj = new shelf(shelf_list[i].StorageZoneId,
|
||||
shelf_list[i].shelfId,
|
||||
shelf_list[i].shelfName,
|
||||
GET_PLANE_LENGTH(),GET_PLANE_WIDTH(),GET_PLANE_HEIGHT(),
|
||||
GET_HOLDER_LENGTH(),GET_HOLDER_WIDTH(),GET_HOLDER_HEIGHT(),
|
||||
shelf_list[i].x,
|
||||
shelf_list[i].y,
|
||||
shelf_list[i].z,
|
||||
GET_LAYER_NUM(),GET_COLUMN_NUM());
|
||||
shelfList.push(shelf_obj);
|
||||
}
|
||||
|
||||
for(var i = 0;i < shelfSize; i++){
|
||||
addStackOfRack(shelfList[i].positionX,shelfList[i].positionY,shelfList[i].positionZ,shelfList[i].planeLength,shelfList[i].planeHeight,shelfList[i].planeWidth,shelfList[i].holderLength,shelfList[i].holderHeight,shelfList[i].holderWidth,scene,shelfList[i].storageZoneId+"$"+shelfList[i].shelfId+"$"+shelfList[i].shelfName,shelfList[i].columnNum,shelfList[i].layerNum);
|
||||
}
|
||||
}
|
||||
|
||||
//region 货物
|
||||
/** 放置单个货物 */
|
||||
function addCargo(x,y,z,box_x,box_y,box_z,scene,name) {
|
||||
var geometry = new THREE.BoxGeometry( box_x, box_y, box_z );
|
||||
var obj = new THREE.Mesh( geometry, CargoMat );
|
||||
obj.position.set(x,y,z);
|
||||
obj.name = name;
|
||||
scene.add(obj);
|
||||
}
|
||||
|
||||
/** 添加单个货位上的货物 */
|
||||
function addOneUnitCargos(shelfId,inLayerNum,inColumnNum,scene) {
|
||||
var storageUnit = getStorageUnitById(shelfId,inLayerNum,inColumnNum);
|
||||
var shelf = getShelfById(storageUnit.shelfId);
|
||||
var storageUnitid = storageUnit.storageUnitId;
|
||||
var x = storageUnit.positionX;
|
||||
var y = storageUnit.positionY + GET_BOX_SIZE()/2 + shelf.planeHeight/2;
|
||||
var z = storageUnit.positionZ;
|
||||
addCargo(x,y,z,GET_BOX_SIZE(),GET_BOX_SIZE(),GET_BOX_SIZE(),scene,"货物"+"$"+storageUnitid)
|
||||
}
|
||||
//endregion
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* @author xiening
|
||||
* Running this will allow you to show white line around objects which you selected.
|
||||
*/
|
||||
/*
|
||||
* 需要在jsp中导入的包
|
||||
<script src="./ThreeJs/three.js"></script>
|
||||
<script src="./ThreeJs/EffectComposer.js"></script>
|
||||
<script src="./ThreeJs/RenderPass.js"></script>
|
||||
<script src="./ThreeJs/OutlinePass.js"></script>
|
||||
<script src="./ThreeJs/FXAAShader.js"></script>
|
||||
<script src="./ThreeJs/ShaderPass.js"></script>
|
||||
<script src="./ThreeJs/CopyShader.js"></script>
|
||||
*/
|
||||
|
||||
THREE.ThreeJs_Composer = function ( _renderer, _scene, _camera, _options, _selectobject) {
|
||||
var raycaster = new THREE.Raycaster();
|
||||
var mouse = new THREE.Vector2();
|
||||
var composer = new THREE.EffectComposer( _renderer );
|
||||
var renderPass = new THREE.RenderPass( _scene, _camera );
|
||||
var selectedObjects = [];
|
||||
composer.addPass( renderPass );
|
||||
var outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), _scene, _camera );
|
||||
outlinePass.edgeStrength = 5;//包围线浓度
|
||||
outlinePass.edgeGlow = 0.5;//边缘线范围
|
||||
outlinePass.edgeThickness = 2;//边缘线浓度
|
||||
outlinePass.pulsePeriod = 2;//包围线闪烁评率
|
||||
outlinePass.visibleEdgeColor.set( '#ffffff' );//包围线颜色
|
||||
outlinePass.hiddenEdgeColor.set( '#190a05' );//被遮挡的边界线颜色
|
||||
composer.addPass( outlinePass );
|
||||
var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
|
||||
effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
|
||||
effectFXAA.renderToScreen = true;
|
||||
// composer.addPass( effectFXAA );
|
||||
|
||||
window.addEventListener( 'click', onMouseClick);
|
||||
window.addEventListener( 'dblclick', onMouseDblClick);
|
||||
|
||||
var door_state_left1 = true; //默认是门是关闭的
|
||||
var door_state_right1 = true; //默认是门是关闭的
|
||||
function onMouseClick( event ) {
|
||||
var x, y;
|
||||
if ( event.changedTouches ) {
|
||||
x = event.changedTouches[ 0 ].pageX;
|
||||
y = event.changedTouches[ 0 ].pageY;
|
||||
} else {
|
||||
x = event.clientX;
|
||||
y = event.clientY;
|
||||
}
|
||||
mouse.x = ( x / window.innerWidth ) * 2 - 1;
|
||||
mouse.y = - ( y / window.innerHeight ) * 2 + 1;
|
||||
raycaster.setFromCamera( mouse, _camera );
|
||||
var intersects = raycaster.intersectObjects( [ _scene ], true );
|
||||
|
||||
if(intersects.length == 0){
|
||||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
||||
return;
|
||||
}
|
||||
if(intersects[0].object.name == "地面" || (intersects[0].object.name == "") || (intersects[0].object.name == "墙面")){
|
||||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
||||
selectedObjects.pop();
|
||||
}else{
|
||||
$("#label").attr("style","display:block;");// 显示说明性标签
|
||||
$("#label").css({left: x, top: y-40});// 修改标签的位置
|
||||
$("#label").text(intersects[0].object.name);// 显示模型信息
|
||||
|
||||
selectedObjects.pop();
|
||||
selectedObjects.push( intersects[0].object );
|
||||
outlinePass.selectedObjects = selectedObjects;//给选中的线条和物体加发光特效
|
||||
}
|
||||
|
||||
var Msg = intersects[0].object.name.split("$");
|
||||
if(Msg[0] == "货物") {
|
||||
_options.batchNo = "一个货物";
|
||||
_options.qty = "100";
|
||||
_options.qtyUom = "kg";
|
||||
_options.qty2 = "10";
|
||||
_options.selectObj = intersects[0].object.name;
|
||||
_selectobject.push( intersects[0].object );
|
||||
}
|
||||
|
||||
if(intersects[0].object.name == "左门1"){
|
||||
if(door_state_left1){
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: -0.5*Math.PI
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_left1 = false;
|
||||
}else{
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_left1 = true;
|
||||
}
|
||||
}else if(intersects[0].object.name == "右门1"){
|
||||
if(door_state_right1){
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0.5*Math.PI
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_right1 = false;
|
||||
}else{
|
||||
new TWEEN.Tween(intersects[0].object.rotation).to({
|
||||
y: 0
|
||||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){
|
||||
}).start();
|
||||
door_state_right1 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDblClick( event ) {
|
||||
var x, y;
|
||||
if ( event.changedTouches ) {
|
||||
x = event.changedTouches[ 0 ].pageX;
|
||||
y = event.changedTouches[ 0 ].pageY;
|
||||
} else {
|
||||
x = event.clientX;
|
||||
y = event.clientY;
|
||||
}
|
||||
mouse.x = ( x / window.innerWidth ) * 2 - 1;
|
||||
mouse.y = - ( y / window.innerHeight ) * 2 + 1;
|
||||
raycaster.setFromCamera( mouse, _camera );
|
||||
var intersects = raycaster.intersectObjects( [ _scene ], true );
|
||||
|
||||
if(intersects.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
var Msg = intersects[0].object.name.split("$");
|
||||
if(Msg[0] == "货物") {
|
||||
var href = "DispatchAction.do?efFormEname=YMIQ083DP&inqu_status-0-storageUnitId=" + Msg[1];
|
||||
EFColorbox({
|
||||
href : href,
|
||||
title:"货物详情",
|
||||
innerWidth:'1200px',
|
||||
innerHeight:'800px',
|
||||
iframe : true,
|
||||
scrolling : false,
|
||||
overlayClose: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return composer;
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* @author xiening
|
||||
* Running this will allow you to drag three.js objects around the screen.
|
||||
*/
|
||||
/*
|
||||
* 需要在jsp中导入的包
|
||||
<script src="./ThreeJs/DragControls.js"></script>
|
||||
<script src="./ThreeJs/TransformControls.js"></script>
|
||||
*/
|
||||
|
||||
THREE.ThreeJs_Drag = function ( _camera, _domElement, _scene, _controls, _isPaused) {
|
||||
// 过滤不是 Mesh 的物体,例如辅助网格
|
||||
var objects = [];
|
||||
for (var i = 0; i < _scene.children.length; i++) {
|
||||
var Msg = _scene.children[i].name.split("$");
|
||||
if (_scene.children[i].isMesh && Msg[0] == "货物") {
|
||||
objects.push(_scene.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var dragControls = new THREE.DragControls( objects, _camera, _domElement );
|
||||
dragControls.addEventListener( 'dragstart', function ( event ) {
|
||||
_controls.enabled = false;
|
||||
_isPaused = true;
|
||||
} );
|
||||
dragControls.addEventListener( 'dragend', function ( event ) {
|
||||
_controls.enabled = true;
|
||||
_isPaused = false;
|
||||
} );
|
||||
// // 添加平移控件
|
||||
// var transformControls = new THREE.TransformControls(_camera, _domElement);
|
||||
// transformControls.addEventListener( 'change', function () {
|
||||
// cancelHideTransform();
|
||||
// } );
|
||||
// transformControls.addEventListener( 'mouseDown', function () {
|
||||
// cancelHideTransform();
|
||||
// } );
|
||||
// transformControls.addEventListener( 'mouseUp', function () {
|
||||
// delayHideTransform();
|
||||
// } );
|
||||
// _scene.add(transformControls);
|
||||
//
|
||||
// // 过滤不是 Mesh 的物体,例如辅助网格
|
||||
// var objects = [];
|
||||
// for (var i = 0; i < _scene.children.length; i++) {
|
||||
// var Msg = _scene.children[i].name.split("$");
|
||||
// if (_scene.children[i].isMesh && Msg[0] == "货物") {
|
||||
// objects.push(_scene.children[i]);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 初始化拖拽控件
|
||||
// var dragControls = new THREE.DragControls(objects, _camera, _domElement);
|
||||
//
|
||||
// // 鼠标划入过事件
|
||||
// dragControls.addEventListener('hoveron', function (event) {
|
||||
// // 让变换控件对象和选中的对象绑定
|
||||
// transformControls.attach(event.object);
|
||||
// cancelHideTransform();
|
||||
// });
|
||||
//
|
||||
// // 鼠标划出事件
|
||||
// dragControls.addEventListener('hoveroff', function (event) {
|
||||
// delayHideTransform();
|
||||
// });
|
||||
//
|
||||
// // 开始拖拽
|
||||
// dragControls.addEventListener('dragstart', function (event) {
|
||||
// controls.enabled = false;
|
||||
// });
|
||||
//
|
||||
// // 拖拽结束
|
||||
// dragControls.addEventListener('dragend', function (event) {
|
||||
// controls.enabled = true;
|
||||
// });
|
||||
//
|
||||
// controls.addEventListener( 'start', function () {
|
||||
// cancelHideTransform();
|
||||
// } );
|
||||
//
|
||||
// controls.addEventListener( 'end', function () {
|
||||
// delayHideTransform();
|
||||
// } );
|
||||
//
|
||||
// var hiding;
|
||||
// function delayHideTransform() {
|
||||
// cancelHideTransform();
|
||||
// hideTransform();
|
||||
// }
|
||||
//
|
||||
// function hideTransform() {
|
||||
// hiding = setTimeout( function () {
|
||||
// transformControls.detach( transformControls.object );
|
||||
// }, 1000 );
|
||||
// }
|
||||
//
|
||||
// function cancelHideTransform() {
|
||||
// if ( hiding ) clearTimeout( hiding );
|
||||
// }
|
||||
//
|
||||
// return transformControls;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* 这是模型的静态常量配置
|
||||
* 和货架的配置(一般要从数据库读取,这里仅做演示)
|
||||
* @author 谢宁, Created on 2020-01-07
|
||||
*/
|
||||
/** ***************************************************************** */
|
||||
|
||||
var PLANE_LENGTH = 24; //货架板面长度
|
||||
var PLANE_WIDTH = 55; //货架板面宽度
|
||||
var PLANE_HEIGHT = 2; //货架板面高度
|
||||
var HOLDER_LENGTH = 2; //支架长度
|
||||
var HOLDER_WIDTH = 2; //支架宽度
|
||||
var HOLDER_HEIGHT = 25; //支架高度
|
||||
var LAYER_NUM = 3; //货架层数
|
||||
var COLUMN_NUM = 2; //货架每层列数
|
||||
var BOX_SIZE = 16; //货物的大小(立方体)
|
||||
|
||||
//货架数组
|
||||
var shelf_list = new Array();
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A1',shelfName:'货架A1',x:-100,y:27,z:0});
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A2',shelfName:'货架A2',x:0,y:27,z:0});
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A3',shelfName:'货架A3',x:100,y:27,z:0});
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A4',shelfName:'货架A4',x:200,y:27,z:0});
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A5',shelfName:'货架A5',x:300,y:27,z:0});
|
||||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A6',shelfName:'货架A6',x:400,y:27,z:0});
|
||||
|
||||
function GET_PLANE_LENGTH(){
|
||||
return PLANE_LENGTH;
|
||||
}
|
||||
|
||||
function GET_PLANE_WIDTH(){
|
||||
return PLANE_WIDTH;
|
||||
}
|
||||
|
||||
function GET_PLANE_HEIGHT(){
|
||||
return PLANE_HEIGHT;
|
||||
}
|
||||
|
||||
function GET_HOLDER_LENGTH(){
|
||||
return HOLDER_LENGTH;
|
||||
}
|
||||
|
||||
function GET_HOLDER_WIDTH(){
|
||||
return HOLDER_WIDTH;
|
||||
}
|
||||
|
||||
function GET_HOLDER_HEIGHT(){
|
||||
return HOLDER_HEIGHT;
|
||||
}
|
||||
|
||||
function GET_LAYER_NUM(){
|
||||
return LAYER_NUM;
|
||||
}
|
||||
|
||||
function GET_COLUMN_NUM(){
|
||||
return COLUMN_NUM;
|
||||
}
|
||||
|
||||
function GET_BOX_SIZE(){
|
||||
return BOX_SIZE;
|
||||
}
|
||||
|
||||
function GET_SHELF_LIST(){
|
||||
return shelf_list;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 960 B |
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 473 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 945 KiB |