From f4bdca486d56156ff72a8c8e29c6aa194fc87fbe Mon Sep 17 00:00:00 2001 From: tengge <930372551@qq.com> Date: Fri, 12 Jun 2020 21:56:34 +0800 Subject: [PATCH] vector4 --- server/three/vector4.go | 1162 +++++++++++++++++++-------------------- 1 file changed, 565 insertions(+), 597 deletions(-) diff --git a/server/three/vector4.go b/server/three/vector4.go index b4bfa35a..b4251c47 100644 --- a/server/three/vector4.go +++ b/server/three/vector4.go @@ -1,5 +1,3 @@ -// +build ignore - // Copyright 2017-2020 The ShadowEditor Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -12,670 +10,640 @@ package three -/** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ - - function Vector4( x, y, z, w ) { - - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; - + func NewVector4( x, y, z, w float64) *Vector4 { + return &Vector4{x,y,z,w} } -Object.defineProperties( Vector4.prototype, { +type Vector4 struct { + X float64 + Y float64 + Z float64 + W float64 +} - "width": { +func (v Vector4)Width() float64 { + return v.Z +} - get: function () { +func (v Vector4)SetWidth(value float64) *Vector4 { + v.Z = value + return &v +} - return this.z; +func (v Vector4)Height() float64 { + return v.W +} - }, +func (v Vector4)SetHeight(value float64) *Vector4 { + v.W = value + return &v +} - set: function ( value ) { +set: function ( x, y, z, w ) { - this.z = value; + this.x = x; + this.y = y; + this.z = z; + this.w = w; - } + return this; - }, +}, - "height": { +setScalar: function ( scalar ) { - get: function () { + this.x = scalar; + this.y = scalar; + this.z = scalar; + this.w = scalar; - return this.w; + return this; - }, +}, - set: function ( value ) { +setX: function ( x ) { - this.w = value; + this.x = x; - } + return this; + +}, + +setY: function ( y ) { + + this.y = y; + + return this; + +}, + +setZ: function ( z ) { + + this.z = z; + + return this; + +}, + +setW: function ( w ) { + + this.w = w; + + return this; + +}, + +setComponent: function ( index, value ) { + + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + case 3: this.w = value; break; + default: throw new Error( 'index is out of range: ' + index ); } -} ); + return this; -Object.assign( Vector4.prototype, { +}, - isVector4: true, +getComponent: function ( index ) { - set: function ( x, y, z, w ) { + switch ( index ) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + case 3: return this.w; + default: throw new Error( 'index is out of range: ' + index ); - return this; + } - }, +}, - setScalar: function ( scalar ) { +clone: function () { - this.x = scalar; - this.y = scalar; - this.z = scalar; - this.w = scalar; + return new this.constructor( this.x, this.y, this.z, this.w ); - return this; +}, - }, +copy: function ( v1 ) { - setX: function ( x ) { + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = ( v1.w !== undefined ) ? v1.w : 1; - this.x = x; + return this; - return this; +}, - }, +add: function ( v1, w ) { - setY: function ( y ) { + if ( w !== undefined ) { - this.y = y; + console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v1, w ); - return this; + } - }, + this.x += v1.x; + this.y += v1.y; + this.z += v1.z; + this.w += v1.w; - setZ: function ( z ) { + return this; - this.z = z; +}, - return this; +addScalar: function ( s ) { - }, + this.x += s; + this.y += s; + this.z += s; + this.w += s; - setW: function ( w ) { + return this; - this.w = w; +}, - return this; +addVectors: function ( a, b ) { - }, + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; + this.w = a.w + b.w; - setComponent: function ( index, value ) { + return this; - switch ( index ) { +}, - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error( 'index is out of range: ' + index ); +addScaledVector: function ( v1, s ) { + + this.x += v1.x * s; + this.y += v1.y * s; + this.z += v1.z * s; + this.w += v1.w * s; + + return this; + +}, + +sub: function ( v1, w ) { + + if ( w !== undefined ) { + + console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + return this.subVectors( v1, w ); + + } + + this.x -= v1.x; + this.y -= v1.y; + this.z -= v1.z; + this.w -= v1.w; + + return this; + +}, + +subScalar: function ( s ) { + + this.x -= s; + this.y -= s; + this.z -= s; + this.w -= s; + + return this; + +}, + +subVectors: function ( a, b ) { + + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; + this.w = a.w - b.w; + + return this; + +}, + +multiplyScalar: function ( scalar ) { + + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; + + return this; + +}, + +applyMatrix4: function ( m ) { + + var x = this.x, y = this.y, z = this.z, w = this.w; + var e = m.elements; + + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; + + return this; + +}, + +divideScalar: function ( scalar ) { + + return this.multiplyScalar( 1 / scalar ); + +}, + +setAxisAngleFromQuaternion: function ( q ) { + + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + + // q is assumed to be normalized + + this.w = 2 * Math.acos( q.w ); + + var s = Math.sqrt( 1 - q.w * q.w ); + + if ( s < 0.0001 ) { + + this.x = 1; + this.y = 0; + this.z = 0; + + } else { + + this.x = q.x / s; + this.y = q.y / s; + this.z = q.z / s; + + } + + return this; + +}, + +setAxisAngleFromRotationMatrix: function ( m ) { + + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + + var angle, x, y, z, // variables for result + epsilon = 0.01, // margin to allow for rounding errors + epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees + + te = m.elements, + + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { + + // singularity found + // first check for identity matrix which must have +1 for all terms + // in leading diagonal and zero in other terms + + if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && + ( Math.abs( m13 + m31 ) < epsilon2 ) && + ( Math.abs( m23 + m32 ) < epsilon2 ) && + ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { + + // this singularity is identity matrix so angle = 0 + + this.set( 1, 0, 0, 0 ); + + return this; // zero angle, arbitrary axis } - return this; + // otherwise this singularity is angle = 180 - }, + angle = Math.PI; - getComponent: function ( index ) { + var xx = ( m11 + 1 ) / 2; + var yy = ( m22 + 1 ) / 2; + var zz = ( m33 + 1 ) / 2; + var xy = ( m12 + m21 ) / 4; + var xz = ( m13 + m31 ) / 4; + var yz = ( m23 + m32 ) / 4; - switch ( index ) { + if ( ( xx > yy ) && ( xx > zz ) ) { - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error( 'index is out of range: ' + index ); + // m11 is the largest diagonal term - } + if ( xx < epsilon ) { - }, - - clone: function () { - - return new this.constructor( this.x, this.y, this.z, this.w ); - - }, - - copy: function ( v ) { - - this.x = v.x; - this.y = v.y; - this.z = v.z; - this.w = ( v.w !== undefined ) ? v.w : 1; - - return this; - - }, - - add: function ( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } - - this.x += v.x; - this.y += v.y; - this.z += v.z; - this.w += v.w; - - return this; - - }, - - addScalar: function ( s ) { - - this.x += s; - this.y += s; - this.z += s; - this.w += s; - - return this; - - }, - - addVectors: function ( a, b ) { - - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - this.w = a.w + b.w; - - return this; - - }, - - addScaledVector: function ( v, s ) { - - this.x += v.x * s; - this.y += v.y * s; - this.z += v.z * s; - this.w += v.w * s; - - return this; - - }, - - sub: function ( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - - } - - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; - - return this; - - }, - - subScalar: function ( s ) { - - this.x -= s; - this.y -= s; - this.z -= s; - this.w -= s; - - return this; - - }, - - subVectors: function ( a, b ) { - - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - this.w = a.w - b.w; - - return this; - - }, - - multiplyScalar: function ( scalar ) { - - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - this.w *= scalar; - - return this; - - }, - - applyMatrix4: function ( m ) { - - var x = this.x, y = this.y, z = this.z, w = this.w; - var e = m.elements; - - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; - this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; - - return this; - - }, - - divideScalar: function ( scalar ) { - - return this.multiplyScalar( 1 / scalar ); - - }, - - setAxisAngleFromQuaternion: function ( q ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - - // q is assumed to be normalized - - this.w = 2 * Math.acos( q.w ); - - var s = Math.sqrt( 1 - q.w * q.w ); - - if ( s < 0.0001 ) { - - this.x = 1; - this.y = 0; - this.z = 0; - - } else { - - this.x = q.x / s; - this.y = q.y / s; - this.z = q.z / s; - - } - - return this; - - }, - - setAxisAngleFromRotationMatrix: function ( m ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - var angle, x, y, z, // variables for result - epsilon = 0.01, // margin to allow for rounding errors - epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - - te = m.elements, - - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - - if ( ( Math.abs( m12 - m21 ) < epsilon ) && - ( Math.abs( m13 - m31 ) < epsilon ) && - ( Math.abs( m23 - m32 ) < epsilon ) ) { - - // singularity found - // first check for identity matrix which must have +1 for all terms - // in leading diagonal and zero in other terms - - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && - ( Math.abs( m13 + m31 ) < epsilon2 ) && - ( Math.abs( m23 + m32 ) < epsilon2 ) && - ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { - - // this singularity is identity matrix so angle = 0 - - this.set( 1, 0, 0, 0 ); - - return this; // zero angle, arbitrary axis - - } - - // otherwise this singularity is angle = 180 - - angle = Math.PI; - - var xx = ( m11 + 1 ) / 2; - var yy = ( m22 + 1 ) / 2; - var zz = ( m33 + 1 ) / 2; - var xy = ( m12 + m21 ) / 4; - var xz = ( m13 + m31 ) / 4; - var yz = ( m23 + m32 ) / 4; - - if ( ( xx > yy ) && ( xx > zz ) ) { - - // m11 is the largest diagonal term - - if ( xx < epsilon ) { - - x = 0; - y = 0.707106781; - z = 0.707106781; - - } else { - - x = Math.sqrt( xx ); - y = xy / x; - z = xz / x; - - } - - } else if ( yy > zz ) { - - // m22 is the largest diagonal term - - if ( yy < epsilon ) { - - x = 0.707106781; - y = 0; - z = 0.707106781; - - } else { - - y = Math.sqrt( yy ); - x = xy / y; - z = yz / y; - - } + x = 0; + y = 0.707106781; + z = 0.707106781; } else { - // m33 is the largest diagonal term so base result on this - - if ( zz < epsilon ) { - - x = 0.707106781; - y = 0.707106781; - z = 0; - - } else { - - z = Math.sqrt( zz ); - x = xz / z; - y = yz / z; - - } + x = Math.sqrt( xx ); + y = xy / x; + z = xz / x; } - this.set( x, y, z, angle ); + } else if ( yy > zz ) { - return this; // return 180 deg rotation + // m22 is the largest diagonal term + + if ( yy < epsilon ) { + + x = 0.707106781; + y = 0; + z = 0.707106781; + + } else { + + y = Math.sqrt( yy ); + x = xy / y; + z = yz / y; + + } + + } else { + + // m33 is the largest diagonal term so base result on this + + if ( zz < epsilon ) { + + x = 0.707106781; + y = 0.707106781; + z = 0; + + } else { + + z = Math.sqrt( zz ); + x = xz / z; + y = yz / z; + + } } - // as we have reached here there are no singularities so we can handle normally + this.set( x, y, z, angle ); - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + - ( m13 - m31 ) * ( m13 - m31 ) + - ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize - - if ( Math.abs( s ) < 0.001 ) s = 1; - - // prevent divide by zero, should not happen if matrix is orthogonal and should be - // caught by singularity test above, but I've left it in just in case - - this.x = ( m32 - m23 ) / s; - this.y = ( m13 - m31 ) / s; - this.z = ( m21 - m12 ) / s; - this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); - - return this; - - }, - - min: function ( v ) { - - this.x = Math.min( this.x, v.x ); - this.y = Math.min( this.y, v.y ); - this.z = Math.min( this.z, v.z ); - this.w = Math.min( this.w, v.w ); - - return this; - - }, - - max: function ( v ) { - - this.x = Math.max( this.x, v.x ); - this.y = Math.max( this.y, v.y ); - this.z = Math.max( this.z, v.z ); - this.w = Math.max( this.w, v.w ); - - return this; - - }, - - clamp: function ( min, max ) { - - // assumes min < max, componentwise - - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - this.w = Math.max( min.w, Math.min( max.w, this.w ) ); - - return this; - - }, - - clampScalar: function ( minVal, maxVal ) { - - this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); - this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); - this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); - this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); - - return this; - - }, - - clampLength: function ( min, max ) { - - var length = this.length(); - - return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); - - }, - - floor: function () { - - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); - - return this; - - }, - - ceil: function () { - - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); - - return this; - - }, - - round: function () { - - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - this.w = Math.round( this.w ); - - return this; - - }, - - roundToZero: function () { - - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); - - return this; - - }, - - negate: function () { - - this.x = - this.x; - this.y = - this.y; - this.z = - this.z; - this.w = - this.w; - - return this; - - }, - - dot: function ( v ) { - - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; - - }, - - lengthSq: function () { - - return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; - - }, - - length: function () { - - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); - - }, - - manhattanLength: function () { - - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); - - }, - - normalize: function () { - - return this.divideScalar( this.length() || 1 ); - - }, - - setLength: function ( length ) { - - return this.normalize().multiplyScalar( length ); - - }, - - lerp: function ( v, alpha ) { - - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; - this.w += ( v.w - this.w ) * alpha; - - return this; - - }, - - lerpVectors: function ( v1, v2, alpha ) { - - this.x = v1.x + ( v2.x - v1.x ) * alpha; - this.y = v1.y + ( v2.y - v1.y ) * alpha; - this.z = v1.z + ( v2.z - v1.z ) * alpha; - this.w = v1.w + ( v2.w - v1.w ) * alpha; - - return this; - - }, - - equals: function ( v ) { - - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); - - }, - - fromArray: function ( array, offset ) { - - if ( offset === undefined ) offset = 0; - - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; - this.w = array[ offset + 3 ]; - - return this; - - }, - - toArray: function ( array, offset ) { - - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; - - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; - array[ offset + 3 ] = this.w; - - return array; - - }, - - fromBufferAttribute: function ( attribute, index, offset ) { - - if ( offset !== undefined ) { - - console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); - - } - - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); - this.w = attribute.getW( index ); - - return this; - - }, - - random: function () { - - this.x = Math.random(); - this.y = Math.random(); - this.z = Math.random(); - this.w = Math.random(); - - return this; + return this; // return 180 deg rotation } -} ); \ No newline at end of file + // as we have reached here there are no singularities so we can handle normally + + var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + + ( m13 - m31 ) * ( m13 - m31 ) + + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + + if ( Math.abs( s ) < 0.001 ) s = 1; + + // prevent divide by zero, should not happen if matrix is orthogonal and should be + // caught by singularity test above, but I've left it in just in case + + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + + return this; + +}, + +min: function ( v1 ) { + + this.x = Math.min( this.x, v1.x ); + this.y = Math.min( this.y, v1.y ); + this.z = Math.min( this.z, v1.z ); + this.w = Math.min( this.w, v1.w ); + + return this; + +}, + +max: function ( v1 ) { + + this.x = Math.max( this.x, v1.x ); + this.y = Math.max( this.y, v1.y ); + this.z = Math.max( this.z, v1.z ); + this.w = Math.max( this.w, v1.w ); + + return this; + +}, + +clamp: function ( min, max ) { + + // assumes min < max, componentwise + + this.x = Math.max( min.x, Math.min( max.x, this.x ) ); + this.y = Math.max( min.y, Math.min( max.y, this.y ) ); + this.z = Math.max( min.z, Math.min( max.z, this.z ) ); + this.w = Math.max( min.w, Math.min( max.w, this.w ) ); + + return this; + +}, + +clampScalar: function ( minVal, maxVal ) { + + this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); + this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); + this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); + this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); + + return this; + +}, + +clampLength: function ( min, max ) { + + var length = this.length(); + + return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); + +}, + +floor: function () { + + this.x = Math.floor( this.x ); + this.y = Math.floor( this.y ); + this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); + + return this; + +}, + +ceil: function () { + + this.x = Math.ceil( this.x ); + this.y = Math.ceil( this.y ); + this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); + + return this; + +}, + +round: function () { + + this.x = Math.round( this.x ); + this.y = Math.round( this.y ); + this.z = Math.round( this.z ); + this.w = Math.round( this.w ); + + return this; + +}, + +roundToZero: function () { + + this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); + this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); + this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); + + return this; + +}, + +negate: function () { + + this.x = - this.x; + this.y = - this.y; + this.z = - this.z; + this.w = - this.w; + + return this; + +}, + +dot: function ( v1 ) { + + return this.x * v1.x + this.y * v1.y + this.z * v1.z + this.w * v1.w; + +}, + +lengthSq: function () { + + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + +}, + +length: function () { + + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); + +}, + +manhattanLength: function () { + + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + +}, + +normalize: function () { + + return this.divideScalar( this.length() || 1 ); + +}, + +setLength: function ( length ) { + + return this.normalize().multiplyScalar( length ); + +}, + +lerp: function ( v1, alpha ) { + + this.x += ( v1.x - this.x ) * alpha; + this.y += ( v1.y - this.y ) * alpha; + this.z += ( v1.z - this.z ) * alpha; + this.w += ( v1.w - this.w ) * alpha; + + return this; + +}, + +lerpVectors: function ( v1, v2, alpha ) { + + this.x = v1.x + ( v2.x - v1.x ) * alpha; + this.y = v1.y + ( v2.y - v1.y ) * alpha; + this.z = v1.z + ( v2.z - v1.z ) * alpha; + this.w = v1.w + ( v2.w - v1.w ) * alpha; + + return this; + +}, + +equals: function ( v1 ) { + + return ( ( v1.x === this.x ) && ( v1.y === this.y ) && ( v1.z === this.z ) && ( v1.w === this.w ) ); + +}, + +fromArray: function ( array, offset ) { + + if ( offset === undefined ) offset = 0; + + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; + + return this; + +}, + +toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; + + return array; + +}, + +fromBufferAttribute: function ( attribute, index, offset ) { + + if ( offset !== undefined ) { + + console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); + + } + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); + + return this; + +}, + +random: function () { + + this.x = Math.random(); + this.y = Math.random(); + this.z = Math.random(); + this.w = Math.random(); + + return this; + +} \ No newline at end of file