From 1b5e8697fbcbbc2a99517e8e49fc607b88c4e071 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 13 Feb 2015 11:41:58 -0800 Subject: [PATCH 001/418] modification on the managment of the light map shading --- .../render-utils/src/DeferredBufferWrite.slh | 6 +++--- .../render-utils/src/DeferredLighting.slh | 18 +++++++++++++----- .../src/directional_ambient_light.slf | 2 +- ...ional_ambient_light_cascaded_shadow_map.slf | 2 +- .../directional_ambient_light_shadow_map.slf | 2 +- .../render-utils/src/directional_light.slf | 2 +- .../directional_light_cascaded_shadow_map.slf | 2 +- .../src/directional_light_shadow_map.slf | 2 +- libraries/render-utils/src/model_lightmap.slf | 2 +- .../src/model_lightmap_normal_map.slf | 11 +++++++++-- .../src/model_lightmap_normal_specular_map.slf | 2 +- .../src/model_lightmap_specular_map.slf | 2 +- 12 files changed, 34 insertions(+), 19 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 066e0198b1..25c90939ac 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -27,11 +27,11 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, gl_FragData[2] = vec4(specular, shininess / 128.0); } -void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) { +void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec4 lightmap) { gl_FragData[0] = vec4(diffuse.rgb, alpha); - //gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5); - gl_FragData[2] = vec4(emissive, shininess / 128.0); + //gl_FragData[2] = vec4(emissive, shininess / 128.0); + gl_FragData[2] = lightmap; } void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index cd65fd1053..81aa4cabaf 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -71,7 +71,7 @@ vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, v } -vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { +vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec4 lightmap) { float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); @@ -79,17 +79,25 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve // it should be just 0, but we have innacurracy so we need to overshoot const float PERPENDICULAR_THRESHOLD = -0.005; float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - + + //float normalMapContrib = (lightmap.w != 0.0 ? diffuseDot * abs(2*lightmap.w - 1.0) : 1.0); + // float normalMapContrib = (lightmap.w != 0.0 ? diffuseDot * abs(2*lightmap.w - 1.0) : 1.0); + float normalMapContrib = 2.0 * (lightmap.w - 0.5); + // evaluate the shadow test but only relevant for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; + lightAttenuation *= (normalMapContrib * max(0, diffuseDot) - (1.0 - normalMapContrib)); + // diffuse light is the lightmap dimmed by shadow - vec3 diffuseLight = lightAttenuation * lightmap; + vec3 diffuseLight = lightAttenuation * lightmap.rgb; // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; + vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap.rgb; - return diffuse * (ambientLight + diffuseLight); + + // return normal; + return diffuse * (ambientLight + diffuseLight); } diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 803bd5ac30..05bc7329e4 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -26,7 +26,7 @@ void main(void) { 1.0, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index 5f88c558d3..2250efec01 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -33,7 +33,7 @@ void main(void) { shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index 6c241853e3..107382620b 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -34,7 +34,7 @@ void main(void) { shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 8ff6cd6c87..dc1d140e2e 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -26,7 +26,7 @@ void main(void) { 1.0, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index ccf8909b64..df6e24964f 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -33,7 +33,7 @@ void main(void) { shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 13435e9101..dce2388ac4 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -34,7 +34,7 @@ void main(void) { shadowAttenuation, frag.normal, frag.diffuse, - frag.specularVal.xyz), + frag.specularVal), 1.0); } else { vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 59836e9737..be9418634b 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -42,5 +42,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb, getMaterialSpecular(mat), getMaterialShininess(mat), - (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); + vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 6310ab0086..3e55675106 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -39,7 +39,7 @@ void main(void) { vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5); + vec3 localNormal = normalize(vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5)); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); @@ -47,6 +47,13 @@ void main(void) { vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + // WE have lightmap AND normal map so we are going to alter the lighting intensity + // from the lightmap with the dot product between the surface normal and the normal map + // Why will you ask? because we want to see something out of the normal map and since + // the lighting from the lightmap doesnt't give a light direction, we just hack one... + vec4 lightIntensity = vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, + 0.5 * dot(localNormal, vec3(0.0, 1.0, 0.0)) + 0.5 ); + Material mat = getMaterial(); packDeferredFragmentLightmap( @@ -55,5 +62,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb, getMaterialSpecular(mat), getMaterialShininess(mat), - (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); + lightIntensity); } diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index ab555ea0c0..9564071d64 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -59,5 +59,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), - (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); + vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); } diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 2973882e8a..b511e1d976 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -45,5 +45,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), - (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); + vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); } From d51cab3e3d58cec59be452ece77d2d8ae3034f50 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 16 Sep 2015 14:51:08 -0700 Subject: [PATCH 002/418] Replace particle velocity with speed and orientation --- examples/example/entities/particlesTest.js | 23 ++-- .../entities/src/EntityItemProperties.cpp | 35 +++--- libraries/entities/src/EntityItemProperties.h | 9 +- .../entities/src/EntityItemPropertiesMacros.h | 8 ++ libraries/entities/src/EntityPropertyFlags.h | 3 + .../entities/src/ParticleEffectEntityItem.cpp | 106 +++++++++--------- .../entities/src/ParticleEffectEntityItem.h | 23 ++-- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 9 files changed, 125 insertions(+), 85 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 0d1ea60005..b9d046e3a0 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -26,22 +26,22 @@ case 0: print("Simple emitter"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, + speedSpread: 0.0, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, radiusSpread: 0.0, animationIsPlaying: true }); break; case 1: - print("Velocity spread"); + print("Speed spread"); Entities.editEntity(particles, { - velocitySpread: { x: 0.1, y: 0.0, z: 0.1 } + speedSpread: 0.1 }); break; case 2: print("Acceleration spread"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, + speedSpread: 0.0, accelerationSpread: { x: 0.0, y: 0.1, z: 0.0 } }); break; @@ -116,7 +116,8 @@ } function setUp() { - var spawnPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))), + var spawnPoint, + boxPoint, animation = { fps: 30, frameIndex: 0, @@ -126,9 +127,14 @@ loop: true }; + boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); + boxPoint = Vec3.sum(boxPoint, { x: 0.0, y: -0.5, z: 0.0 }); + spawnPoint = Vec3.sum(boxPoint, { x: 0.0, y: 0.75, z: 0.0 }); + box = Entities.addEntity({ type: "Box", - position: spawnPoint, + name: "ParticlesTest Box", + position: boxPoint, dimensions: { x: 0.3, y: 0.3, z: 0.3 }, color: { red: 128, green: 128, blue: 128 }, lifetime: 3600 // 1 hour; just in case @@ -136,12 +142,13 @@ particles = Entities.addEntity({ type: "ParticleEffect", + name: "ParticlesTest Effect", position: spawnPoint, particleRadius: PARTICLE_RADIUS, radiusSpread: 0.0, emitRate: 2.0, - emitVelocity: { x: 0.0, y: 1.0, z: 0.0 }, - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, + emitSpeed: 1.0, + speedSpread: 0.0, emitAcceleration: { x: 0.0, y: -0.3, z: 0.0 }, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index dbcad8a328..af228d92de 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -91,8 +91,9 @@ CONSTRUCT_PROPERTY(shapeType, SHAPE_TYPE_NONE), CONSTRUCT_PROPERTY(maxParticles, ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES), CONSTRUCT_PROPERTY(lifespan, ParticleEffectEntityItem::DEFAULT_LIFESPAN), CONSTRUCT_PROPERTY(emitRate, ParticleEffectEntityItem::DEFAULT_EMIT_RATE), -CONSTRUCT_PROPERTY(emitVelocity, ParticleEffectEntityItem::DEFAULT_EMIT_VELOCITY), -CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD), +CONSTRUCT_PROPERTY(emitSpeed, ParticleEffectEntityItem::DEFAULT_EMIT_SPEED), +CONSTRUCT_PROPERTY(speedSpread, ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD), +CONSTRUCT_PROPERTY(emitOrientation, ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION), CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), @@ -374,8 +375,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_MAX_PARTICLES, maxParticles); CHECK_PROPERTY_CHANGE(PROP_LIFESPAN, lifespan); CHECK_PROPERTY_CHANGE(PROP_EMIT_RATE, emitRate); - CHECK_PROPERTY_CHANGE(PROP_EMIT_VELOCITY, emitVelocity); - CHECK_PROPERTY_CHANGE(PROP_VELOCITY_SPREAD, velocitySpread); + CHECK_PROPERTY_CHANGE(PROP_EMIT_SPEED, emitSpeed); + CHECK_PROPERTY_CHANGE(PROP_SPEED_SPREAD, speedSpread); + CHECK_PROPERTY_CHANGE(PROP_EMIT_ORIENTATION, emitOrientation); CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); @@ -493,8 +495,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(maxParticles); COPY_PROPERTY_TO_QSCRIPTVALUE(lifespan); COPY_PROPERTY_TO_QSCRIPTVALUE(emitRate); - COPY_PROPERTY_TO_QSCRIPTVALUE(emitVelocity); - COPY_PROPERTY_TO_QSCRIPTVALUE(velocitySpread); + COPY_PROPERTY_TO_QSCRIPTVALUE(emitSpeed); + COPY_PROPERTY_TO_QSCRIPTVALUE(speedSpread); + COPY_PROPERTY_TO_QSCRIPTVALUE(emitOrientation); COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); @@ -632,8 +635,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate); - COPY_PROPERTY_FROM_QSCRIPTVALUE(emitVelocity, glmVec3, setEmitVelocity); - COPY_PROPERTY_FROM_QSCRIPTVALUE(velocitySpread, glmVec3, setVelocitySpread); + COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); + COPY_PROPERTY_FROM_QSCRIPTVALUE(speedSpread, float, setSpeedSpread); + COPY_PROPERTY_FROM_QSCRIPTVALUE(emitOrientation, glmQuat, setEmitOrientation); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); @@ -885,8 +889,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, properties.getEmitRate()); - APPEND_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, properties.getEmitVelocity()); - APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, properties.getVelocitySpread()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, properties.getEmitSpeed()); + APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, properties.getSpeedSpread()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, properties.getEmitOrientation()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); @@ -1169,8 +1174,9 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_VELOCITY, glm::vec3, setEmitVelocity); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY_SPREAD, glm::vec3, setVelocitySpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); @@ -1318,8 +1324,9 @@ void EntityItemProperties::markAllChanged() { _maxParticlesChanged = true; _lifespanChanged = true; _emitRateChanged = true; - _emitVelocityChanged = true; - _velocitySpreadChanged = true; + _emitSpeedChanged = true; + _speedSpreadChanged = true; + _emitOrientationChanged = true; _emitAccelerationChanged = true; _accelerationSpreadChanged = true; _particleRadiusChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index cec6b456a7..10ef4164ab 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -138,8 +138,9 @@ public: DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float); DEFINE_PROPERTY(PROP_EMIT_RATE, EmitRate, emitRate, float); - DEFINE_PROPERTY_REF(PROP_EMIT_VELOCITY, EmitVelocity, emitVelocity, glm::vec3); - DEFINE_PROPERTY_REF(PROP_VELOCITY_SPREAD, VelocitySpread, velocitySpread, glm::vec3); + DEFINE_PROPERTY(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, float); + DEFINE_PROPERTY(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, float); + DEFINE_PROPERTY_REF(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat); DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); @@ -335,7 +336,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, MaxParticles, maxParticles, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifespan, lifespan, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRate, emitRate, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitVelocity, emitVelocity, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitSpeed, emitSpeed, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, SpeedSpread, speedSpread, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitOrientation, emitOrientation, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index a3e31024d1..e7ff53026e 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -44,6 +44,14 @@ } \ } +#define SKIP_ENTITY_PROPERTY(P,T) \ + if (propertyFlags.getHasProperty(P)) { \ + T fromBuffer; \ + int bytes = OctreePacketData::unpackDataFromBytes(dataAt, fromBuffer); \ + dataAt += bytes; \ + bytesRead += bytes; \ + } + #define DECODE_GROUP_PROPERTY_HAS_CHANGED(P,N) \ if (propertyFlags.getHasProperty(P)) { \ set##N##Changed(true); \ diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index d4f880ed8f..3de8541984 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -160,6 +160,9 @@ enum EntityPropertyList { PROP_ALPHA_SPREAD, PROP_ALPHA_START, PROP_ALPHA_FINISH, + PROP_EMIT_SPEED, + PROP_SPEED_SPREAD, + PROP_EMIT_ORIENTATION, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index b1229b8bb6..25de20166c 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -43,6 +43,9 @@ #include "EntityScriptingInterface.h" #include "ParticleEffectEntityItem.h" +const glm::vec3 X_AXIS = glm::vec3(1.0f, 0.0f, 0.0f); +const glm::vec3 Z_AXIS = glm::vec3(0.0f, 0.0f, 1.0f); + const xColor ParticleEffectEntityItem::DEFAULT_COLOR = { 255, 255, 255 }; const xColor ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; @@ -55,8 +58,9 @@ const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; -const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_VELOCITY(0.0f, 5.0f, 0.0f); -const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3.0f); +const float ParticleEffectEntityItem::DEFAULT_EMIT_SPEED = 5.0f; +const float ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD = 1.0f; +const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; @@ -104,13 +108,18 @@ ParticleEffectEntityItem::~ParticleEffectEntityItem() { } -void ParticleEffectEntityItem::setEmitVelocity(const glm::vec3& emitVelocity) { - _emitVelocity = emitVelocity; +void ParticleEffectEntityItem::setEmitSpeed(float emitSpeed) { + _emitSpeed = emitSpeed; computeAndUpdateDimensions(); } -void ParticleEffectEntityItem::setVelocitySpread(const glm::vec3& velocitySpread) { - _velocitySpread = velocitySpread; +void ParticleEffectEntityItem::setSpeedSpread(float speedSpread) { + _speedSpread = speedSpread; + computeAndUpdateDimensions(); +} + +void ParticleEffectEntityItem::setEmitOrientation(const glm::quat& emitOrientation) { + _emitOrientation = emitOrientation; computeAndUpdateDimensions(); } @@ -126,23 +135,18 @@ void ParticleEffectEntityItem::setAccelerationSpread(const glm::vec3& accelerati void ParticleEffectEntityItem::computeAndUpdateDimensions() { const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error - - float maxVelocityX = fabsf(_velocity.x) + _velocitySpread.x; - float maxAccelerationX = fabsf(_acceleration.x) + _accelerationSpread.x; - float maxXDistance = (maxVelocityX * time) + (0.5f * maxAccelerationX * time * time); - - float maxVelocityY = fabsf(_velocity.y) + _velocitySpread.y; - float maxAccelerationY = fabsf(_acceleration.y) + _accelerationSpread.y; - float maxYDistance = (maxVelocityY * time) + (0.5f * maxAccelerationY * time * time); - - float maxVelocityZ = fabsf(_velocity.z) + _velocitySpread.z; - float maxAccelerationZ = fabsf(_acceleration.z) + _accelerationSpread.z; - float maxZDistance = (maxVelocityZ * time) + (0.5f * maxAccelerationZ * time * time); - - float maxDistance = std::max(maxXDistance, std::max(maxYDistance, maxZDistance)); - + + glm::vec3 velocity = _emitSpeed * (_emitOrientation * Z_AXIS); + glm::vec3 velocitySpread = _speedSpread * (_emitOrientation * Z_AXIS); + + glm::vec3 maxVelocity = glm::abs(velocity) + velocitySpread; + glm::vec3 maxAccleration = glm::abs(_acceleration) + _accelerationSpread; + glm::vec3 maxDistance = time * maxVelocity + (0.5f * time * time) * maxAccleration; + + float maxDistanceValue = std::max(maxDistance.x, std::max(maxDistance.y, maxDistance.z)); + //times 2 because dimensions are diameters not radii - glm::vec3 dims(2.0f * maxDistance); + glm::vec3 dims(2.0f * maxDistanceValue); EntityItem::setDimensions(dims); } @@ -161,8 +165,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocitySpread, getVelocitySpread); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitSpeed, getEmitSpeed); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(speedSpread, getSpeedSpread); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitOrientation, getEmitOrientation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(accelerationSpread, getAccelerationSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); @@ -194,8 +199,9 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRate, setEmitRate); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitVelocity, setEmitVelocity); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocitySpread, setVelocitySpread); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitSpeed, setEmitSpeed); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(speedSpread, setSpeedSpread); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitOrientation, setEmitOrientation); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); @@ -258,20 +264,24 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); - READ_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, glm::vec3, setEmitVelocity); + if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + SKIP_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, glm::vec3); + } if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_MODIFICATIONS) { READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - READ_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, glm::vec3, setVelocitySpread); + if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + SKIP_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, glm::vec3); + } } else { - // EMIT_STRENGTH FAKEOUT + // EMIT_ACCELERATION FAKEOUT READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - // LOCAL_GRAVITY FAKEOUT + // ACCELERATION_SPREAD FAKEOUT READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - // ACTUALLY PARTICLE RADIUS + // ACTUAL PARTICLE_RADIUS READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); } @@ -292,6 +302,12 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish); } + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); + READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); + READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); + } + return bytesRead; } @@ -309,12 +325,10 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_MAX_PARTICLES; requestedProperties += PROP_LIFESPAN; requestedProperties += PROP_EMIT_RATE; - requestedProperties += PROP_EMIT_VELOCITY; requestedProperties += PROP_EMIT_ACCELERATION; requestedProperties += PROP_ACCELERATION_SPREAD; requestedProperties += PROP_PARTICLE_RADIUS; requestedProperties += PROP_TEXTURES; - requestedProperties += PROP_VELOCITY_SPREAD; requestedProperties += PROP_RADIUS_SPREAD; requestedProperties += PROP_RADIUS_START; requestedProperties += PROP_RADIUS_FINISH; @@ -325,6 +339,9 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_ALPHA_SPREAD; requestedProperties += PROP_ALPHA_START; requestedProperties += PROP_ALPHA_FINISH; + requestedProperties += PROP_EMIT_SPEED; + requestedProperties += PROP_SPEED_SPREAD; + requestedProperties += PROP_EMIT_ORIENTATION; return requestedProperties; } @@ -347,12 +364,10 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, getEmitRate()); - APPEND_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, getEmitVelocity()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, getParticleRadius()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); - APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, getVelocitySpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); @@ -363,6 +378,9 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, getAlphaStart()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, getAlphaFinish()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, getEmitSpeed()); + APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, getSpeedSpread()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, getEmitOrientation()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { @@ -614,7 +632,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _radiusMiddles[i] =_particleRadius; _radiusFinishes[i] = getRadiusFinish(); } else { - float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; + float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1.0f) * _radiusSpread / _particleRadius; _radiusStarts[i] = spreadMultiplier * getRadiusStart(); _radiusMiddles[i] = spreadMultiplier * _particleRadius; _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); @@ -622,21 +640,9 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { updateRadius(i, 0.0f); // Velocity and acceleration - glm::vec3 spreadOffset; - spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f); - spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f); - spreadOffset.z = -_velocitySpread.z + randFloat() * (_velocitySpread.z * 2.0f); - - // set initial conditions _particlePositions[i] = getPosition(); - _particleVelocities[i] = _emitVelocity + spreadOffset; - - spreadOffset.x = -_accelerationSpread.x + randFloat() * (_accelerationSpread.x * 2.0f); - spreadOffset.y = -_accelerationSpread.y + randFloat() * (_accelerationSpread.y * 2.0f); - spreadOffset.z = -_accelerationSpread.z + randFloat() * (_accelerationSpread.z * 2.0f); - - _particleAccelerations[i] = _emitAcceleration + spreadOffset; - + _particleVelocities[i] = (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); + _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 802ff25af3..429f6e02ba 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -128,13 +128,17 @@ public: void setEmitRate(float emitRate) { _emitRate = emitRate; } float getEmitRate() const { return _emitRate; } - static const glm::vec3 DEFAULT_EMIT_VELOCITY; - void setEmitVelocity(const glm::vec3& emitVelocity); - const glm::vec3& getEmitVelocity() const { return _emitVelocity; } - - static const glm::vec3 DEFAULT_VELOCITY_SPREAD; - void setVelocitySpread(const glm::vec3& velocitySpread); - const glm::vec3& getVelocitySpread() const { return _velocitySpread; } + static const float DEFAULT_EMIT_SPEED; + void setEmitSpeed(float emitSpeed); + float getEmitSpeed() const { return _emitSpeed; } + + static const float DEFAULT_SPEED_SPREAD; + void setSpeedSpread(float speedSpread); + float getSpeedSpread() const { return _speedSpread; } + + static const glm::quat DEFAULT_EMIT_ORIENTATION; + void setEmitOrientation(const glm::quat& emitOrientation); + const glm::quat& getEmitOrientation() const { return _emitOrientation; } static const glm::vec3 DEFAULT_EMIT_ACCELERATION; void setEmitAcceleration(const glm::vec3& emitAcceleration); @@ -202,8 +206,9 @@ protected: quint32 _maxParticles = DEFAULT_MAX_PARTICLES; float _lifespan = DEFAULT_LIFESPAN; float _emitRate = DEFAULT_EMIT_RATE; - glm::vec3 _emitVelocity = DEFAULT_EMIT_VELOCITY; - glm::vec3 _velocitySpread = DEFAULT_VELOCITY_SPREAD; + float _emitSpeed = DEFAULT_EMIT_SPEED; + float _speedSpread = DEFAULT_SPEED_SPREAD; + glm::quat _emitOrientation = DEFAULT_EMIT_ORIENTATION; glm::vec3 _emitAcceleration = DEFAULT_EMIT_ACCELERATION; glm::vec3 _accelerationSpread = DEFAULT_ACCELERATION_SPREAD; float _particleRadius = DEFAULT_PARTICLE_RADIUS; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 7e00acfdc0..5552836a9a 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,7 +38,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_PROTOCOL_HEADER_SWAP; + return VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER; default: return 14; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index da702358a1..5f6fb18814 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -140,5 +140,6 @@ const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40; const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; +const PacketVersion VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER = 44; #endif // hifi_PacketHeaders_h From c99210736389e9fddda618b06cb86d5387957783 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 16 Sep 2015 18:07:18 -0700 Subject: [PATCH 003/418] Add particle properties ready to use for emitting from a spheroid --- .../entities/src/EntityItemProperties.cpp | 42 +++++++++++++++++ libraries/entities/src/EntityItemProperties.h | 16 ++++++- libraries/entities/src/EntityPropertyFlags.h | 6 +++ .../entities/src/ParticleEffectEntityItem.cpp | 46 ++++++++++++++++++- .../entities/src/ParticleEffectEntityItem.h | 30 ++++++++++++ 5 files changed, 136 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index af228d92de..7702657790 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -94,6 +94,12 @@ CONSTRUCT_PROPERTY(emitRate, ParticleEffectEntityItem::DEFAULT_EMIT_RATE), CONSTRUCT_PROPERTY(emitSpeed, ParticleEffectEntityItem::DEFAULT_EMIT_SPEED), CONSTRUCT_PROPERTY(speedSpread, ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD), CONSTRUCT_PROPERTY(emitOrientation, ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION), +CONSTRUCT_PROPERTY(emitRadius, ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS), +CONSTRUCT_PROPERTY(emitRadiusStart, ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START), +CONSTRUCT_PROPERTY(polarStart, ParticleEffectEntityItem::DEFAULT_POLAR_START), +CONSTRUCT_PROPERTY(polarFinish, ParticleEffectEntityItem::DEFAULT_POLAR_FINISH), +CONSTRUCT_PROPERTY(azimuthStart, ParticleEffectEntityItem::DEFAULT_AZIMUTH_START), +CONSTRUCT_PROPERTY(azimuthFinish, ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH), CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), @@ -378,6 +384,12 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_SPEED, emitSpeed); CHECK_PROPERTY_CHANGE(PROP_SPEED_SPREAD, speedSpread); CHECK_PROPERTY_CHANGE(PROP_EMIT_ORIENTATION, emitOrientation); + CHECK_PROPERTY_CHANGE(PROP_EMIT_RADIUS, emitRadius); + CHECK_PROPERTY_CHANGE(PROP_EMIT_RADIUS_START, emitRadiusStart); + CHECK_PROPERTY_CHANGE(PROP_POLAR_START, polarStart); + CHECK_PROPERTY_CHANGE(PROP_POLAR_FINISH, polarFinish); + CHECK_PROPERTY_CHANGE(PROP_AZIMUTH_START, azimuthStart); + CHECK_PROPERTY_CHANGE(PROP_AZIMUTH_FINISH, azimuthFinish); CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); @@ -498,6 +510,12 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(emitSpeed); COPY_PROPERTY_TO_QSCRIPTVALUE(speedSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(emitOrientation); + COPY_PROPERTY_TO_QSCRIPTVALUE(emitRadius); + COPY_PROPERTY_TO_QSCRIPTVALUE(emitRadiusStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(polarStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(polarFinish); + COPY_PROPERTY_TO_QSCRIPTVALUE(azimuthStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(azimuthFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); @@ -638,6 +656,12 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); COPY_PROPERTY_FROM_QSCRIPTVALUE(speedSpread, float, setSpeedSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitOrientation, glmQuat, setEmitOrientation); + COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRadius, glmVec3, setEmitRadius); + COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRadiusStart, float, setEmitRadiusStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(polarStart, float, setPolarStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(polarFinish, float, setPolarFinish); + COPY_PROPERTY_FROM_QSCRIPTVALUE(azimuthStart, float, setAzimuthStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(azimuthFinish, float, setAzimuthFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); @@ -892,6 +916,12 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, properties.getEmitSpeed()); APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, properties.getSpeedSpread()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, properties.getEmitOrientation()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS, properties.getEmitRadius()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, properties.getEmitRadiusStart()); + APPEND_ENTITY_PROPERTY(PROP_POLAR_START, properties.getPolarStart()); + APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, properties.getPolarFinish()); + APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_START, properties.getAzimuthStart()); + APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, properties.getAzimuthFinish()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); @@ -1177,6 +1207,12 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS, glm::vec3, setEmitRadius); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_START, float, setPolarStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_FINISH, float, setPolarFinish); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_START, float, setAzimuthStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); @@ -1327,6 +1363,12 @@ void EntityItemProperties::markAllChanged() { _emitSpeedChanged = true; _speedSpreadChanged = true; _emitOrientationChanged = true; + _emitRadiusChanged = true; + _emitRadiusStartChanged = true; + _polarStartChanged = true; + _polarFinishChanged = true; + _azimuthStartChanged = true; + _azimuthFinishChanged = true; _emitAccelerationChanged = true; _accelerationSpreadChanged = true; _particleRadiusChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 10ef4164ab..8e899d7651 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -141,8 +141,14 @@ public: DEFINE_PROPERTY(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, float); DEFINE_PROPERTY(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, float); DEFINE_PROPERTY_REF(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat); - DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); - DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); + DEFINE_PROPERTY_REF(PROP_EMIT_RADIUS, EmitRadius, emitRadius, glm::vec3); + DEFINE_PROPERTY(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float); + DEFINE_PROPERTY(PROP_POLAR_START, PolarStart, polarStart, float); + DEFINE_PROPERTY(PROP_POLAR_FINISH, PolarFinish, polarFinish, float); + DEFINE_PROPERTY(PROP_AZIMUTH_START, AzimuthStart, azimuthStart, float); + DEFINE_PROPERTY(PROP_AZIMUTH_FINISH, AzimuthFinish, azimuthFinish, float); + DEFINE_PROPERTY_REF(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); + DEFINE_PROPERTY_REF(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float); @@ -339,6 +345,12 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitSpeed, emitSpeed, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, SpeedSpread, speedSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitOrientation, emitOrientation, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRadius, emitRadius, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRadiusStart, emitRadiusStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, PolarStart, polarStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, PolarFinish, polarFinish, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AzimuthStart, azimuthStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AzimuthFinish, azimuthFinish, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 3de8541984..741cfabf92 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -163,6 +163,12 @@ enum EntityPropertyList { PROP_EMIT_SPEED, PROP_SPEED_SPREAD, PROP_EMIT_ORIENTATION, + PROP_EMIT_RADIUS, + PROP_EMIT_RADIUS_START, + PROP_POLAR_START, + PROP_POLAR_FINISH, + PROP_AZIMUTH_START, + PROP_AZIMUTH_FINISH, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 25de20166c..2e5ce09aa0 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -60,7 +60,13 @@ const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_SPEED = 5.0f; const float ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD = 1.0f; -const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); +const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); // Vertical +const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS = glm::vec3(0.0f, 0.0f, 0.0f); // Emit from point +const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitRadius > 0) +const float ParticleEffectEntityItem::DEFAULT_POLAR_START = 0.0f; // Emit along z-axis +const float ParticleEffectEntityItem::DEFAULT_POLAR_FINISH = 0.0f; // "" +const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) +const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH = -PI; // "" const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; @@ -123,6 +129,12 @@ void ParticleEffectEntityItem::setEmitOrientation(const glm::quat& emitOrientati computeAndUpdateDimensions(); } + +void ParticleEffectEntityItem::setEmitRadius(const glm::vec3& emitRadius) { + _emitRadius = emitRadius; + computeAndUpdateDimensions(); +} + void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) { _emitAcceleration = emitAcceleration; computeAndUpdateDimensions(); @@ -141,7 +153,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() { glm::vec3 maxVelocity = glm::abs(velocity) + velocitySpread; glm::vec3 maxAccleration = glm::abs(_acceleration) + _accelerationSpread; - glm::vec3 maxDistance = time * maxVelocity + (0.5f * time * time) * maxAccleration; + glm::vec3 maxDistance = _emitRadius + time * maxVelocity + (0.5f * time * time) * maxAccleration; float maxDistanceValue = std::max(maxDistance.x, std::max(maxDistance.y, maxDistance.z)); @@ -168,6 +180,12 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitSpeed, getEmitSpeed); COPY_ENTITY_PROPERTY_TO_PROPERTIES(speedSpread, getSpeedSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitOrientation, getEmitOrientation); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRadius, getEmitRadius); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRadiusStart, getEmitRadiusStart); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(polarStart, getPolarStart); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(polarFinish, getPolarFinish); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(azimuthStart, getAzimuthStart); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(azimuthFinish, getAzimuthFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(accelerationSpread, getAccelerationSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); @@ -202,6 +220,12 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitSpeed, setEmitSpeed); SET_ENTITY_PROPERTY_FROM_PROPERTIES(speedSpread, setSpeedSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitOrientation, setEmitOrientation); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRadius, setEmitRadius); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRadiusStart, setEmitRadiusStart); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(polarStart, setPolarStart); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(polarFinish, setPolarFinish); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(azimuthStart, setAzimuthStart); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(azimuthFinish, setAzimuthFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); @@ -306,6 +330,12 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); + READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS, glm::vec3, setEmitRadius); + READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); + READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart); + READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish); + READ_ENTITY_PROPERTY(PROP_AZIMUTH_START, float, setAzimuthStart); + READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); } return bytesRead; @@ -342,6 +372,12 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_EMIT_SPEED; requestedProperties += PROP_SPEED_SPREAD; requestedProperties += PROP_EMIT_ORIENTATION; + requestedProperties += PROP_EMIT_RADIUS; + requestedProperties += PROP_EMIT_RADIUS_START; + requestedProperties += PROP_POLAR_START; + requestedProperties += PROP_POLAR_FINISH; + requestedProperties += PROP_AZIMUTH_START; + requestedProperties += PROP_AZIMUTH_FINISH; return requestedProperties; } @@ -381,6 +417,12 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, getEmitSpeed()); APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, getSpeedSpread()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, getEmitOrientation()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS, getEmitRadius()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, getEmitRadiusStart()); + APPEND_ENTITY_PROPERTY(PROP_POLAR_START, getPolarStart()); + APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, getPolarFinish()); + APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_START, getAzimuthStart()); + APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, getAzimuthFinish()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 429f6e02ba..d5ec4eb587 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -140,6 +140,30 @@ public: void setEmitOrientation(const glm::quat& emitOrientation); const glm::quat& getEmitOrientation() const { return _emitOrientation; } + static const glm::vec3 DEFAULT_EMIT_RADIUS; + void setEmitRadius(const glm::vec3& emitRadius); + const glm::vec3& getEmitRadius() const { return _emitRadius; } + + static const float DEFAULT_EMIT_RADIUS_START; + void setEmitRadiusStart(float emitRadiusStart) { _emitRadiusStart = emitRadiusStart; } + float getEmitRadiusStart() const { return _emitRadiusStart; } + + static const float DEFAULT_POLAR_START; + void setPolarStart(float polarStart) { _polarStart = polarStart; } + float getPolarStart() const { return _polarStart; } + + static const float DEFAULT_POLAR_FINISH; + void setPolarFinish(float polarFinish) { _polarFinish = polarFinish; } + float getPolarFinish() const { return _polarFinish; } + + static const float DEFAULT_AZIMUTH_START; + void setAzimuthStart(float azimuthStart) { _azimuthStart = azimuthStart; } + float getAzimuthStart() const { return _azimuthStart; } + + static const float DEFAULT_AZIMUTH_FINISH; + void setAzimuthFinish(float azimuthFinish) { _azimuthFinish = azimuthFinish; } + float getAzimuthFinish() const { return _azimuthFinish; } + static const glm::vec3 DEFAULT_EMIT_ACCELERATION; void setEmitAcceleration(const glm::vec3& emitAcceleration); const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; } @@ -209,6 +233,12 @@ protected: float _emitSpeed = DEFAULT_EMIT_SPEED; float _speedSpread = DEFAULT_SPEED_SPREAD; glm::quat _emitOrientation = DEFAULT_EMIT_ORIENTATION; + glm::vec3 _emitRadius = DEFAULT_EMIT_RADIUS; + float _emitRadiusStart = DEFAULT_EMIT_RADIUS_START; + float _polarStart = DEFAULT_POLAR_START; + float _polarFinish = DEFAULT_POLAR_FINISH; + float _azimuthStart = DEFAULT_AZIMUTH_START; + float _azimuthFinish = DEFAULT_AZIMUTH_FINISH; glm::vec3 _emitAcceleration = DEFAULT_EMIT_ACCELERATION; glm::vec3 _accelerationSpread = DEFAULT_ACCELERATION_SPREAD; float _particleRadius = DEFAULT_PARTICLE_RADIUS; From b9985031dacaa6e762a7f717a1562840e473f702 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 09:03:42 -0700 Subject: [PATCH 004/418] adding blocks --- examples/acScripts/toybox.js | 17 ++++++++++ examples/toybox/spawners/blockSpawner.js | 43 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 examples/acScripts/toybox.js create mode 100644 examples/toybox/spawners/blockSpawner.js diff --git a/examples/acScripts/toybox.js b/examples/acScripts/toybox.js new file mode 100644 index 0000000000..f4b9fc3d95 --- /dev/null +++ b/examples/acScripts/toybox.js @@ -0,0 +1,17 @@ +//TODO: Figure out why importing svo is only working locally + +print("SHNUR SHNUR SHNUR") + +var light = Entities.addEntity({ + type: "Box", + position: {x: 493, y: 505, z: 602}, + dimensions: {x: 3, y: 3, z: 3}, + color: {red: 200, green : 10, blue: 200} +}); + + +// function cleanup() { +// Entities.deleteEntity(light); +// } + +// Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/spawners/blockSpawner.js new file mode 100644 index 0000000000..b62f62b594 --- /dev/null +++ b/examples/toybox/spawners/blockSpawner.js @@ -0,0 +1,43 @@ +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +var BASE_DIMENSIONS = Vec3.multiply({x: 0.2, y: 0.1, z: 0.8}, 0.2); +var NUM_BLOCKS = 4; + +var blocks = []; + +spawnBlocks(); + +var table = Entities.addEntity({ + type: "Box", + position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), + dimensions: {x: 2, y: .01, z: 2}, + color: {red: 20, green: 20, blue: 20} +}) +function spawnBlocks() { + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: center, + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), + collisionsWillMove: true, + gravity: {x: 0, y: -9.8, z: 0}, + velocity: {x: 0, y: -.01, z: 0} + + }); + blocks.push(block); + } +} + +function cleanup() { + Entities.deleteEntity(table); + blocks.forEach(function(block) { + Entities.deleteEntity(block); + }); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 7ffcce589dcf30405cde806d99fc2d5dbfd188e6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 09:09:25 -0700 Subject: [PATCH 005/418] blocks spawning --- examples/toybox/spawners/blockSpawner.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/spawners/blockSpawner.js index b62f62b594..2ea17988f0 100644 --- a/examples/toybox/spawners/blockSpawner.js +++ b/examples/toybox/spawners/blockSpawner.js @@ -9,18 +9,18 @@ var blocks = []; spawnBlocks(); -var table = Entities.addEntity({ - type: "Box", - position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), - dimensions: {x: 2, y: .01, z: 2}, - color: {red: 20, green: 20, blue: 20} -}) +// var table = Entities.addEntity({ +// type: "Box", +// position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), +// dimensions: {x: 2, y: .01, z: 2}, +// color: {red: 20, green: 20, blue: 20} +// }) function spawnBlocks() { for (var i = 0; i < NUM_BLOCKS; i++) { var block = Entities.addEntity({ type: "Model", modelURL: modelUrl, - position: center, + position: {x: 548.3, y:495.55, z:504.4}, shapeType: 'box', name: "block", dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), @@ -34,10 +34,10 @@ function spawnBlocks() { } function cleanup() { - Entities.deleteEntity(table); - blocks.forEach(function(block) { - Entities.deleteEntity(block); - }); + // Entities.deleteEntity(table); +// blocks.forEach(function(block) { +// Entities.deleteEntity(block); +// }); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From c5b7de2156fb3d8ad099712968036c158c5240a5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 10:00:01 -0700 Subject: [PATCH 006/418] added fire spawner --- examples/toybox/spawners/fireSpawner.js | 103 ++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 examples/toybox/spawners/fireSpawner.js diff --git a/examples/toybox/spawners/fireSpawner.js b/examples/toybox/spawners/fireSpawner.js new file mode 100644 index 0000000000..b361c6bdfb --- /dev/null +++ b/examples/toybox/spawners/fireSpawner.js @@ -0,0 +1,103 @@ +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +} +var totalTime = 0; +var FIRE_COLOR = { + red: 255, + green: 255, + blue: 255 +}; +var minLightIntensity = 3; +var maxLightIntensity = 11; + +var minTimeFactor = .1; +var maxTimeFactor = 1; + +var LIGHT_COLOR = { + red: 255, + green: 100, + blue: 28 +} + +var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 +}); + + +var fire = Entities.addEntity({ + type: "ParticleEffect", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 + }, + emitRate: 100, + colorStart: { + red: 46, + green: 39, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + emitVelocity: { + x: .0, + y: 0.1, + z: 0 + }, + + velocitySpread: { + x: .1, + y: .01, + z: .1 + }, + radiusSpread: .1, + radiusStart: .1, + particleRadius: .05, + radiusFinish: 0.01, + + alphaStart: 0.5, + alpha: 1, + alphaFinish: 0.0, + emitAcceleration: { + x: 0.1, + y: 1, + z: .0 + }, + accelerationSpread: { + x: .01, + y: .1, + z: .01 + }, + lifespan: 2 +}); + + +function cleanup() { + Entities.deleteEntity(fire); +} +Script.scriptEnding.connect(cleanup); + +function randFloat(min, max) { + return Math.random() * (max - min) + min; +} + +function randInt(min, max) { + return Math.floor(Math.random() * (max - min)) + min; +} \ No newline at end of file From cdae5452ceca496f252b1bf1f9d3509fe2009045 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 14:21:11 -0700 Subject: [PATCH 007/418] going ac script route for entity reset --- examples/acScripts/toybox.js | 17 --- .../{spawners => managers}/blockSpawner.js | 0 examples/toybox/managers/fireManager.js | 103 ++++++++++++++++++ examples/toybox/managers/lightSpawner.js | 14 +++ examples/toybox/masterResetEntity.js | 14 +++ examples/toybox/masterResetEntitySpawner.js | 19 ++++ examples/toybox/spawners/fireSpawner.js | 103 ------------------ 7 files changed, 150 insertions(+), 120 deletions(-) delete mode 100644 examples/acScripts/toybox.js rename examples/toybox/{spawners => managers}/blockSpawner.js (100%) create mode 100644 examples/toybox/managers/fireManager.js create mode 100644 examples/toybox/managers/lightSpawner.js create mode 100644 examples/toybox/masterResetEntity.js create mode 100644 examples/toybox/masterResetEntitySpawner.js delete mode 100644 examples/toybox/spawners/fireSpawner.js diff --git a/examples/acScripts/toybox.js b/examples/acScripts/toybox.js deleted file mode 100644 index f4b9fc3d95..0000000000 --- a/examples/acScripts/toybox.js +++ /dev/null @@ -1,17 +0,0 @@ -//TODO: Figure out why importing svo is only working locally - -print("SHNUR SHNUR SHNUR") - -var light = Entities.addEntity({ - type: "Box", - position: {x: 493, y: 505, z: 602}, - dimensions: {x: 3, y: 3, z: 3}, - color: {red: 200, green : 10, blue: 200} -}); - - -// function cleanup() { -// Entities.deleteEntity(light); -// } - -// Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/managers/blockSpawner.js similarity index 100% rename from examples/toybox/spawners/blockSpawner.js rename to examples/toybox/managers/blockSpawner.js diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js new file mode 100644 index 0000000000..15afb0d5ea --- /dev/null +++ b/examples/toybox/managers/fireManager.js @@ -0,0 +1,103 @@ +FireManager = function() { + + this.reset = function() { + if (!this.fire) { + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + var ZERO_VEC = { + x: 0, + y: 0, + z: 0 + } + var totalTime = 0; + var FIRE_COLOR = { + red: 255, + green: 255, + blue: 255 + }; + var minLightIntensity = 3; + var maxLightIntensity = 11; + + var minTimeFactor = .1; + var maxTimeFactor = 1; + + var LIGHT_COLOR = { + red: 255, + green: 100, + blue: 28 + } + + var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 + }); + + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + + this.fire = Entities.addEntity({ + type: "ParticleEffect", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 + }, + name: "fire", + emitRate: 100, + colorStart: { + red: 46, + green: 39, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + emitVelocity: { + x: .0, + y: 0.1, + z: 0 + }, + + velocitySpread: { + x: .1, + y: .01, + z: .1 + }, + radiusSpread: .1, + radiusStart: .1, + particleRadius: .05, + radiusFinish: 0.01, + + alphaStart: 0.5, + alpha: 1, + alphaFinish: 0.0, + emitAcceleration: { + x: 0.1, + y: 1, + z: .0 + }, + accelerationSpread: { + x: .01, + y: .1, + z: .01 + }, + lifespan: 2 + }); + + } else { + Entities.deleteEntity(this.fire); + this.fire = null; + } + + } +} \ No newline at end of file diff --git a/examples/toybox/managers/lightSpawner.js b/examples/toybox/managers/lightSpawner.js new file mode 100644 index 0000000000..4a52d4775b --- /dev/null +++ b/examples/toybox/managers/lightSpawner.js @@ -0,0 +1,14 @@ +var light = Entities.addEntity({ + type: "light", + position: {x: 544, y: 498.9, z: 506.7}, + intensity: 10, + dimensions: {x: 10, y: 10, z: 10}, + color: {red: 200, green : 10, blue: 200} +}); + + +function cleanup() { + Entities.deleteEntity(light); +} + +Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js new file mode 100644 index 0000000000..cefaa61fe3 --- /dev/null +++ b/examples/toybox/masterResetEntity.js @@ -0,0 +1,14 @@ +var fireScriptURL = Script.resolvePath("managers/fireManager.js"); +Script.include(fireScriptURL); + +var fireManager = new FireManager(); + +fireManager.reset(); + + + +function cleanup() { + fireManager.reset(); +} + +Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/masterResetEntitySpawner.js b/examples/toybox/masterResetEntitySpawner.js new file mode 100644 index 0000000000..8938595d7f --- /dev/null +++ b/examples/toybox/masterResetEntitySpawner.js @@ -0,0 +1,19 @@ +var scriptURL = Script.resolvePath("masterResetEntity.js?v1" + Math.random()); + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1, Quat.getFront(Camera.getOrientation()))); + +var resetEntity = Entities.addEntity({ + type: "Box", + dimensions: {x: .3, y: 0.3, z: 0.3}, + position: center, + color: {red: 100, green: 10, blue: 100}, + script: scriptURL +}); + + + +function cleanup() { + Entities.deleteEntity(resetEntity); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toybox/spawners/fireSpawner.js b/examples/toybox/spawners/fireSpawner.js deleted file mode 100644 index b361c6bdfb..0000000000 --- a/examples/toybox/spawners/fireSpawner.js +++ /dev/null @@ -1,103 +0,0 @@ -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); -var ZERO_VEC = { - x: 0, - y: 0, - z: 0 -} -var totalTime = 0; -var FIRE_COLOR = { - red: 255, - green: 255, - blue: 255 -}; -var minLightIntensity = 3; -var maxLightIntensity = 11; - -var minTimeFactor = .1; -var maxTimeFactor = 1; - -var LIGHT_COLOR = { - red: 255, - green: 100, - blue: 28 -} - -var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 -}); - - -var fire = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 - }, - emitRate: 100, - colorStart: { - red: 46, - green: 39, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - emitVelocity: { - x: .0, - y: 0.1, - z: 0 - }, - - velocitySpread: { - x: .1, - y: .01, - z: .1 - }, - radiusSpread: .1, - radiusStart: .1, - particleRadius: .05, - radiusFinish: 0.01, - - alphaStart: 0.5, - alpha: 1, - alphaFinish: 0.0, - emitAcceleration: { - x: 0.1, - y: 1, - z: .0 - }, - accelerationSpread: { - x: .01, - y: .1, - z: .01 - }, - lifespan: 2 -}); - - -function cleanup() { - Entities.deleteEntity(fire); -} -Script.scriptEnding.connect(cleanup); - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} \ No newline at end of file From 75c1e4956785188ce3aa0f6a2198a5adb34c0018 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 15:32:40 -0700 Subject: [PATCH 008/418] more tweaks yeah --- examples/toybox/managers/blockManager.js | 68 ++++++++++++++++++++++++ examples/toybox/managers/blockSpawner.js | 43 --------------- examples/toybox/masterResetEntity.js | 8 ++- 3 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 examples/toybox/managers/blockManager.js delete mode 100644 examples/toybox/managers/blockSpawner.js diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js new file mode 100644 index 0000000000..3f2ee15151 --- /dev/null +++ b/examples/toybox/managers/blockManager.js @@ -0,0 +1,68 @@ +BlockManager = function() { + + this.spawned = false; + this.blocks = []; + + this.reset = function() { + if (this.spawned) { + this.clearBlocks(); + } else { + this.createBlocks(); + } + + this.spawned = !this.spawned; + } + + this.clearBlocks = function() { + this.blocks.forEach(function(block) { + Entities.deleteEntity(block); + }); + this.blocks = []; + } + + this.createBlocks = function() { + + HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + + var BASE_DIMENSIONS = Vec3.multiply({ + x: 0.2, + y: 0.1, + z: 0.8 + }, 0.2); + var NUM_BLOCKS = 4; + + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: { + x: 548.3, + y: 495.55 + i/5, + z: 504.4 + }, + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, { + x: Math.random() / 10, + y: Math.random() / 10, + z: Math.random() / 10 + }), + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + + }); + this.blocks.push(block); + } + + } +} \ No newline at end of file diff --git a/examples/toybox/managers/blockSpawner.js b/examples/toybox/managers/blockSpawner.js deleted file mode 100644 index 2ea17988f0..0000000000 --- a/examples/toybox/managers/blockSpawner.js +++ /dev/null @@ -1,43 +0,0 @@ -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; -var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); -var BASE_DIMENSIONS = Vec3.multiply({x: 0.2, y: 0.1, z: 0.8}, 0.2); -var NUM_BLOCKS = 4; - -var blocks = []; - -spawnBlocks(); - -// var table = Entities.addEntity({ -// type: "Box", -// position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), -// dimensions: {x: 2, y: .01, z: 2}, -// color: {red: 20, green: 20, blue: 20} -// }) -function spawnBlocks() { - for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ - type: "Model", - modelURL: modelUrl, - position: {x: 548.3, y:495.55, z:504.4}, - shapeType: 'box', - name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), - collisionsWillMove: true, - gravity: {x: 0, y: -9.8, z: 0}, - velocity: {x: 0, y: -.01, z: 0} - - }); - blocks.push(block); - } -} - -function cleanup() { - // Entities.deleteEntity(table); -// blocks.forEach(function(block) { -// Entities.deleteEntity(block); -// }); -} - -Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index cefaa61fe3..783926daad 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -1,14 +1,20 @@ var fireScriptURL = Script.resolvePath("managers/fireManager.js"); Script.include(fireScriptURL); -var fireManager = new FireManager(); +var blockScriptURL = Script.resolvePath("managers/blockManager.js"); +Script.include(blockScriptURL); +var fireManager = new FireManager(); fireManager.reset(); +var blockManager = new BlockManager(); +blockManager.reset(); + function cleanup() { fireManager.reset(); + blockManager.reset(); } Script.scriptEnding.connect(cleanup); From 109f2d8a1afd30d2cb02d7077ad195b63c721655 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 15:39:31 -0700 Subject: [PATCH 009/418] base positions --- examples/toybox/managers/blockManager.js | 10 +++------- examples/toybox/managers/fireManager.js | 12 +++--------- examples/toybox/masterResetEntity.js | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js index 3f2ee15151..7158e4499f 100644 --- a/examples/toybox/managers/blockManager.js +++ b/examples/toybox/managers/blockManager.js @@ -1,5 +1,5 @@ -BlockManager = function() { - +BlockManager = function(position) { + this.position = position; this.spawned = false; this.blocks = []; @@ -36,11 +36,7 @@ BlockManager = function() { var block = Entities.addEntity({ type: "Model", modelURL: modelUrl, - position: { - x: 548.3, - y: 495.55 + i/5, - z: 504.4 - }, + position: Vec3.sum(this.position, {x: 0, y: i/5, z:0}), shapeType: 'box', name: "block", dimensions: Vec3.sum(BASE_DIMENSIONS, { diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js index 15afb0d5ea..30a65698fd 100644 --- a/examples/toybox/managers/fireManager.js +++ b/examples/toybox/managers/fireManager.js @@ -1,5 +1,5 @@ -FireManager = function() { - +FireManager = function(position) { + this.position = position; this.reset = function() { if (!this.fire) { var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); @@ -34,17 +34,11 @@ FireManager = function() { lastFrame: 10000 }); - var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - this.fire = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 - }, + position: this.position, name: "fire", emitRate: 100, colorStart: { diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 783926daad..9612745d93 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -4,10 +4,19 @@ Script.include(fireScriptURL); var blockScriptURL = Script.resolvePath("managers/blockManager.js"); Script.include(blockScriptURL); -var fireManager = new FireManager(); +var fireManager = new FireManager({ + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 +}); + fireManager.reset(); -var blockManager = new BlockManager(); +var blockManager = new BlockManager({ + x: 548.3, + y: 495.55, + z: 504.4 + }); blockManager.reset(); @@ -17,4 +26,4 @@ function cleanup() { blockManager.reset(); } -Script.scriptEnding.connect(cleanup); +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 9614a69b19f48e1fb2b80c5fd9c6961f335e6917 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 16:12:16 -0700 Subject: [PATCH 010/418] adding spray can --- examples/toybox/managers/lightSpawner.js | 14 -------------- examples/toybox/managers/sprayCanManager.js | 0 2 files changed, 14 deletions(-) delete mode 100644 examples/toybox/managers/lightSpawner.js create mode 100644 examples/toybox/managers/sprayCanManager.js diff --git a/examples/toybox/managers/lightSpawner.js b/examples/toybox/managers/lightSpawner.js deleted file mode 100644 index 4a52d4775b..0000000000 --- a/examples/toybox/managers/lightSpawner.js +++ /dev/null @@ -1,14 +0,0 @@ -var light = Entities.addEntity({ - type: "light", - position: {x: 544, y: 498.9, z: 506.7}, - intensity: 10, - dimensions: {x: 10, y: 10, z: 10}, - color: {red: 200, green : 10, blue: 200} -}); - - -function cleanup() { - Entities.deleteEntity(light); -} - -Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/managers/sprayCanManager.js b/examples/toybox/managers/sprayCanManager.js new file mode 100644 index 0000000000..e69de29bb2 From 78642e3c79858f8e3134d43328e90cdeebd570dc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 17:04:09 -0700 Subject: [PATCH 011/418] Getting rid of managers --- examples/toybox/managers/blockManager.js | 64 -------------- examples/toybox/managers/fireManager.js | 97 --------------------- examples/toybox/managers/sprayCanManager.js | 0 examples/toybox/masterResetEntity.js | 97 ++++++++++++++++----- 4 files changed, 77 insertions(+), 181 deletions(-) delete mode 100644 examples/toybox/managers/blockManager.js delete mode 100644 examples/toybox/managers/fireManager.js delete mode 100644 examples/toybox/managers/sprayCanManager.js diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js deleted file mode 100644 index 7158e4499f..0000000000 --- a/examples/toybox/managers/blockManager.js +++ /dev/null @@ -1,64 +0,0 @@ -BlockManager = function(position) { - this.position = position; - this.spawned = false; - this.blocks = []; - - this.reset = function() { - if (this.spawned) { - this.clearBlocks(); - } else { - this.createBlocks(); - } - - this.spawned = !this.spawned; - } - - this.clearBlocks = function() { - this.blocks.forEach(function(block) { - Entities.deleteEntity(block); - }); - this.blocks = []; - } - - this.createBlocks = function() { - - HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - - var BASE_DIMENSIONS = Vec3.multiply({ - x: 0.2, - y: 0.1, - z: 0.8 - }, 0.2); - var NUM_BLOCKS = 4; - - for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ - type: "Model", - modelURL: modelUrl, - position: Vec3.sum(this.position, {x: 0, y: i/5, z:0}), - shapeType: 'box', - name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, { - x: Math.random() / 10, - y: Math.random() / 10, - z: Math.random() / 10 - }), - collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -.01, - z: 0 - } - - }); - this.blocks.push(block); - } - - } -} \ No newline at end of file diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js deleted file mode 100644 index 30a65698fd..0000000000 --- a/examples/toybox/managers/fireManager.js +++ /dev/null @@ -1,97 +0,0 @@ -FireManager = function(position) { - this.position = position; - this.reset = function() { - if (!this.fire) { - var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - var ZERO_VEC = { - x: 0, - y: 0, - z: 0 - } - var totalTime = 0; - var FIRE_COLOR = { - red: 255, - green: 255, - blue: 255 - }; - var minLightIntensity = 3; - var maxLightIntensity = 11; - - var minTimeFactor = .1; - var maxTimeFactor = 1; - - var LIGHT_COLOR = { - red: 255, - green: 100, - blue: 28 - } - - var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 - }); - - this.fire = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: this.position, - name: "fire", - emitRate: 100, - colorStart: { - red: 46, - green: 39, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - emitVelocity: { - x: .0, - y: 0.1, - z: 0 - }, - - velocitySpread: { - x: .1, - y: .01, - z: .1 - }, - radiusSpread: .1, - radiusStart: .1, - particleRadius: .05, - radiusFinish: 0.01, - - alphaStart: 0.5, - alpha: 1, - alphaFinish: 0.0, - emitAcceleration: { - x: 0.1, - y: 1, - z: .0 - }, - accelerationSpread: { - x: .01, - y: .1, - z: .01 - }, - lifespan: 2 - }); - - } else { - Entities.deleteEntity(this.fire); - this.fire = null; - } - - } -} \ No newline at end of file diff --git a/examples/toybox/managers/sprayCanManager.js b/examples/toybox/managers/sprayCanManager.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9612745d93..cb82034f11 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -1,29 +1,86 @@ -var fireScriptURL = Script.resolvePath("managers/fireManager.js"); -Script.include(fireScriptURL); +var utilitiesScript = Script.resolvePath("../libraries/utils.js"); +Script.include(utilitiesScript); -var blockScriptURL = Script.resolvePath("managers/blockManager.js"); -Script.include(blockScriptURL); +var resetKey = "resetMe"; -var fireManager = new FireManager({ - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 -}); - -fireManager.reset(); - -var blockManager = new BlockManager({ - x: 548.3, - y: 495.55, - z: 504.4 - }); -blockManager.reset(); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +//Before creating anything, first search a radius and delete all the things that should be deleted +deleteAllToys(); + +createAllToys(); + + + +function createAllToys() { + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); +} + +function deleteAllToys() { + var entities = Entities.findEntities(MyAvatar.position, 100); + + entities.forEach(function(entity) { + //params: customKey, id, defaultValue + var shouldReset = getEntityCustomData(resetKey, entity, false); + if (shouldReset) { + Entities.deleteEntity(entity); + } + }) +} + +function createBlocks(position) { + print("CREATE BLOCKS") + var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + var BASE_DIMENSIONS = Vec3.multiply({ + x: 0.2, + y: 0.1, + z: 0.8 + }, 0.2); + var NUM_BLOCKS = 4; + + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: Vec3.sum(position, { + x: 0, + y: i / 5, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, { + x: Math.random() / 10, + y: Math.random() / 10, + z: Math.random() / 10 + }), + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + //customKey, id, data + setEntityCustomData(resetKey, block, { + resetMe: true + }); + } +} function cleanup() { - fireManager.reset(); - blockManager.reset(); + deleteAllToys(); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 12e2cf3ce9542b77082209e3ab36c2e80d3f7877 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2015 17:14:35 -0700 Subject: [PATCH 012/418] Emit in all directions from a point or the surface of a spheroid --- examples/example/entities/particlesTest.js | 97 ++++++++++++++++--- .../entities/src/ParticleEffectEntityItem.cpp | 47 +++++++-- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 2 +- libraries/script-engine/src/Vec3.cpp | 25 ----- libraries/script-engine/src/Vec3.h | 4 +- libraries/shared/src/GLMHelpers.cpp | 24 +++++ libraries/shared/src/GLMHelpers.h | 4 + 8 files changed, 157 insertions(+), 48 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index b9d046e3a0..20556be515 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -13,13 +13,25 @@ (function () { var box, + sphere, + sphereDimensions = { x: 0.4, y: 0.8, z: 0.2 }, + pointDimensions = { x: 0.0, y: 0.0, z: 0.0 }, + sphereOrientation = Quat.fromPitchYawRollDegrees(-60.0, 30.0, 0.0), + verticalOrientation = Quat.fromPitchYawRollDegrees(-90.0, 0.0, 0.0), particles, particleExample = -1, - NUM_PARTICLE_EXAMPLES = 11, - PARTICLE_RADIUS = 0.04; + PARTICLE_RADIUS = 0.04, + SLOW_EMIT_RATE = 2.0, + FAST_EMIT_RATE = 100.0, + SLOW_EMIT_SPEED = 0.05, + FAST_EMIT_SPEED = 1.0, + GRAVITY_EMIT_ACCELERATON = { x: 0.0, y: -0.3, z: 0.0 }, + ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 }, + PI = 3.141593, + NUM_PARTICLE_EXAMPLES = 13; function onClickDownOnEntity(entityID) { - if (entityID === box || entityID === particles) { + if (entityID === box || entityID === sphere || entityID === particles) { particleExample = (particleExample + 1) % NUM_PARTICLE_EXAMPLES; switch (particleExample) { @@ -104,20 +116,62 @@ }); break; case 10: - print("Stop emitting"); + print("Emit in all directions from point"); Entities.editEntity(particles, { colorStart: { red: 255, green: 255, blue: 255 }, colorFinish: { red: 255, green: 255, blue: 255 }, + emitRate: FAST_EMIT_RATE, + emitSpeed: SLOW_EMIT_SPEED, + emitAcceleration: ZERO_EMIT_ACCELERATON, + polarFinish: PI + }); + Entities.editEntity(box, { + visible: false + }); + Entities.editEntity(sphere, { + visible: true + }); + break; + case 11: + print("Emit from sphere surface"); + Entities.editEntity(particles, { + colorStart: { red: 255, green: 255, blue: 255 }, + colorFinish: { red: 255, green: 255, blue: 255 }, + emitRadius: sphereDimensions, + emitOrientation: sphereOrientation + }); + Entities.editEntity(box, { + visible: false + }); + Entities.editEntity(sphere, { + visible: true + }); + break; + case 12: + print("Stop emitting"); + Entities.editEntity(particles, { + emitRadius: pointDimensions, + emitOrientation: verticalOrientation, + emitRate: SLOW_EMIT_RATE, + emitSpeed: FAST_EMIT_SPEED, + emitAcceleration: GRAVITY_EMIT_ACCELERATON, + polarFinish: 0.0, animationIsPlaying: false }); + Entities.editEntity(box, { + visible: true + }); + Entities.editEntity(sphere, { + visible: false + }); break; } } } function setUp() { - var spawnPoint, - boxPoint, + var boxPoint, + spawnPoint, animation = { fps: 30, frameIndex: 0, @@ -129,32 +183,48 @@ boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { x: 0.0, y: -0.5, z: 0.0 }); - spawnPoint = Vec3.sum(boxPoint, { x: 0.0, y: 0.75, z: 0.0 }); + spawnPoint = Vec3.sum(boxPoint, { x: 0.0, y: 1.0, z: 0.0 }); box = Entities.addEntity({ type: "Box", name: "ParticlesTest Box", position: boxPoint, + rotation: verticalOrientation, dimensions: { x: 0.3, y: 0.3, z: 0.3 }, color: { red: 128, green: 128, blue: 128 }, - lifetime: 3600 // 1 hour; just in case + lifetime: 3600, // 1 hour; just in case + visible: true }); + // Same size and orientation as emitter when ellipsoid. + sphere = Entities.addEntity({ + type: "Sphere", + name: "ParticlesTest Sphere", + position: boxPoint, + rotation: sphereOrientation, + dimensions: sphereDimensions, + color: { red: 128, green: 128, blue: 128 }, + lifetime: 3600, // 1 hour; just in case + visible: false + }); + + // 1.0m above the box or ellipsoid. particles = Entities.addEntity({ type: "ParticleEffect", - name: "ParticlesTest Effect", + name: "ParticlesTest Emitter", position: spawnPoint, + emitOrientation: verticalOrientation, particleRadius: PARTICLE_RADIUS, radiusSpread: 0.0, - emitRate: 2.0, - emitSpeed: 1.0, + emitRate: SLOW_EMIT_RATE, + emitSpeed: FAST_EMIT_SPEED, speedSpread: 0.0, - emitAcceleration: { x: 0.0, y: -0.3, z: 0.0 }, + emitAcceleration: GRAVITY_EMIT_ACCELERATON, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", color: { red: 255, green: 255, blue: 255 }, lifespan: 5.0, - visible: true, + visible: false, locked: false, animationSettings: animation, animationIsPlaying: false, @@ -170,6 +240,7 @@ Entities.clickDownOnEntity.disconnect(onClickDownOnEntity); Entities.deleteEntity(particles); Entities.deleteEntity(box); + Entities.deleteEntity(sphere); } setUp(); diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 2e5ce09aa0..59a8e126cf 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -288,7 +288,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); - if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { SKIP_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, glm::vec3); } @@ -297,7 +297,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { SKIP_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, glm::vec3); } } else { @@ -326,7 +326,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish); } - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER) { + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); @@ -682,9 +682,44 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { updateRadius(i, 0.0f); // Velocity and acceleration - _particlePositions[i] = getPosition(); - _particleVelocities[i] = (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + if (_polarStart == 0.0f && _polarFinish == 0.0f) { + // Emit along z-axis + _particlePositions[i] = getPosition(); + _particleVelocities[i] = + (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); + _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + + } else if (_emitRadius == glm::vec3()) { + // Emit around point + float elevation = asin(2.0f * randFloat() - 1.0f); // Distribute points evenly over surface + glm::vec3 emitDirection = _emitOrientation * fromSpherical(elevation, randFloat() * TWO_PI); + + _particlePositions[i] = getPosition(); + _particleVelocities[i] = + (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); + _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + + } else { + // Emit from ellipsoid + float elevation = asin(2.0f * randFloat() - 1.0f); // Distribute points approximately evenly over surface + float azimuth = (2.0f * randFloat() - 1.0f) * PI; + // TODO: Sort out ellipsoid equations to distribute completely evenly over surface. + + float x = _emitRadius.x * cos(elevation) * cos(azimuth); + float y = _emitRadius.y * cos(elevation) * sin(azimuth); + float z = _emitRadius.z * sin(elevation); + glm::vec3 emitPosition = glm::vec3(x, y, z); + glm::vec3 emitDirection = glm::normalize(glm::vec3( + x / (_emitRadius.x * _emitRadius.x), + y / (_emitRadius.y * _emitRadius.y), + z / (_emitRadius.z * _emitRadius.z) + )); + + _particlePositions[i] = getPosition() + _emitOrientation * emitPosition; + _particleVelocities[i] = + (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); + _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + } integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 5552836a9a..a8cf743686 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,7 +38,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER; + return VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER; default: return 14; } diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 5f6fb18814..9f3c5950a2 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -140,6 +140,6 @@ const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40; const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; -const PacketVersion VERSION_ENTITIES_PARTICLE_SPHEROID_EMITTER = 44; +const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; #endif // hifi_PacketHeaders_h diff --git a/libraries/script-engine/src/Vec3.cpp b/libraries/script-engine/src/Vec3.cpp index 69961bfd8e..04e3a4fe05 100644 --- a/libraries/script-engine/src/Vec3.cpp +++ b/libraries/script-engine/src/Vec3.cpp @@ -58,28 +58,3 @@ glm::vec3 Vec3::toPolar(const glm::vec3& v) { return glm::vec3(elevation, azimuth, radius); } - -glm::vec3 Vec3::fromPolar(const glm::vec3& polar) { - float x = glm::cos(polar.x) * glm::sin(polar.y); - float y = glm::sin(-polar.x); - float z = glm::cos(polar.x) * glm::cos(polar.y); - - // Round small values to 0 - if (glm::abs(x) < EPSILON) { - x = 0.0f; - } - if (glm::abs(y) < EPSILON) { - y = 0.0f; - } - if (glm::abs(z) < EPSILON) { - z = 0.0f; - } - - return polar.z * glm::vec3(x, y, z); -} - -glm::vec3 Vec3::fromPolar(float elevation, float azimuth) { - glm::vec3 v = glm::vec3(elevation, azimuth, 1.0f); - return fromPolar(v); -} - diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index b05e729a49..2d703ac87e 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -43,8 +43,8 @@ public slots: bool withinEpsilon(const glm::vec3& v1, const glm::vec3& v2, float epsilon); // FIXME misnamed, should be 'spherical' or 'euler' depending on the implementation glm::vec3 toPolar(const glm::vec3& v); - glm::vec3 fromPolar(const glm::vec3& polar); - glm::vec3 fromPolar(float elevation, float azimuth); + glm::vec3 fromPolar(const glm::vec3& polar) { return fromSpherical(polar); } + glm::vec3 fromPolar(float elevation, float azimuth) { return fromSpherical(elevation, azimuth); } const glm::vec3& UNIT_X() { return Vectors::UNIT_X; } const glm::vec3& UNIT_Y() { return Vectors::UNIT_Y; } const glm::vec3& UNIT_Z() { return Vectors::UNIT_Z; } diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 7d56157e53..3d705cf99e 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -225,6 +225,30 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) { return glm::angleAxis(angle, axis); } +glm::vec3 fromSpherical(const glm::vec3& spherical) { + float x = glm::cos(spherical.x) * glm::sin(spherical.y); + float y = glm::sin(-spherical.x); + float z = glm::cos(spherical.x) * glm::cos(spherical.y); + + // Round small values to 0 + if (glm::abs(x) < EPSILON) { + x = 0.0f; + } + if (glm::abs(y) < EPSILON) { + y = 0.0f; + } + if (glm::abs(z) < EPSILON) { + z = 0.0f; + } + + return spherical.z * glm::vec3(x, y, z); +} + +glm::vec3 fromSpherical(float elevation, float azimuth) { + glm::vec3 v = glm::vec3(elevation, azimuth, 1.0f); + return fromSpherical(v); +} + bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) { glm::vec3 v1 = p0 - p1, v2 = p2 - p1; // Non-collinear vectors contained in the plane glm::vec3 n = glm::cross(v1, v2); // Plane's normal vector, pointing out of the triangle diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 6683088306..0245ca926f 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -117,6 +117,10 @@ float angleBetween(const glm::vec3& v1, const glm::vec3& v2); glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2); +glm::vec3 fromSpherical(const glm::vec3& spherical); + +glm::vec3 fromSpherical(float elevation, float azimuth); + bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2); glm::vec3 extractTranslation(const glm::mat4& matrix); From ae795a5c4fad36561332bdf39e2e59373dd40abf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 17:15:59 -0700 Subject: [PATCH 013/418] spray paint spawner working --- examples/entityScripts/sprayPaintCan.js | 1 + examples/toybox/masterResetEntity.js | 52 +++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js index aa04e94341..29ff451b76 100644 --- a/examples/entityScripts/sprayPaintCan.js +++ b/examples/entityScripts/sprayPaintCan.js @@ -238,6 +238,7 @@ Entities.deleteEntity(stroke); }); } + Script.update.connect(this.update); }); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index cb82034f11..964070bd90 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -19,6 +19,12 @@ function createAllToys() { y: 495.55, z: 504.4 }); + + createSprayCan({ + x: 549.12, + y: 495.55, + z: 503.77 + }); } function deleteAllToys() { @@ -33,8 +39,48 @@ function deleteAllToys() { }) } +function createSprayCan(position) { + var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + name: "spraycan", + modelURL: modelURL, + position: position , + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, + collisionsWillMove: true, + shapeType: 'box', + script: scriptURL, + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: -1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + +} + function createBlocks(position) { - print("CREATE BLOCKS") var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; var BASE_DIMENSIONS = Vec3.multiply({ x: 0.2, @@ -44,7 +90,7 @@ function createBlocks(position) { var NUM_BLOCKS = 4; for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ + var entity = Entities.addEntity({ type: "Model", modelURL: modelUrl, position: Vec3.sum(position, { @@ -73,7 +119,7 @@ function createBlocks(position) { }); //customKey, id, data - setEntityCustomData(resetKey, block, { + setEntityCustomData(resetKey, entity, { resetMe: true }); } From f647dcf1472ec793a7046a887115d9e38a3bdb45 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2015 21:06:40 -0700 Subject: [PATCH 014/418] Change emitter radiuses to dimensions to match sphere properties --- examples/example/entities/particlesTest.js | 4 +-- .../entities/src/EntityItemProperties.cpp | 14 ++++---- libraries/entities/src/EntityItemProperties.h | 4 +-- libraries/entities/src/EntityPropertyFlags.h | 2 +- .../entities/src/ParticleEffectEntityItem.cpp | 35 ++++++++++--------- .../entities/src/ParticleEffectEntityItem.h | 8 ++--- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 20556be515..7fe98e3c28 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -137,7 +137,7 @@ Entities.editEntity(particles, { colorStart: { red: 255, green: 255, blue: 255 }, colorFinish: { red: 255, green: 255, blue: 255 }, - emitRadius: sphereDimensions, + emitDimensions: sphereDimensions, emitOrientation: sphereOrientation }); Entities.editEntity(box, { @@ -150,7 +150,7 @@ case 12: print("Stop emitting"); Entities.editEntity(particles, { - emitRadius: pointDimensions, + emitDimensions: pointDimensions, emitOrientation: verticalOrientation, emitRate: SLOW_EMIT_RATE, emitSpeed: FAST_EMIT_SPEED, diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 7702657790..4b50ec0d02 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -94,7 +94,7 @@ CONSTRUCT_PROPERTY(emitRate, ParticleEffectEntityItem::DEFAULT_EMIT_RATE), CONSTRUCT_PROPERTY(emitSpeed, ParticleEffectEntityItem::DEFAULT_EMIT_SPEED), CONSTRUCT_PROPERTY(speedSpread, ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD), CONSTRUCT_PROPERTY(emitOrientation, ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION), -CONSTRUCT_PROPERTY(emitRadius, ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS), +CONSTRUCT_PROPERTY(emitDimensions, ParticleEffectEntityItem::DEFAULT_EMIT_DIMENSIONS), CONSTRUCT_PROPERTY(emitRadiusStart, ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START), CONSTRUCT_PROPERTY(polarStart, ParticleEffectEntityItem::DEFAULT_POLAR_START), CONSTRUCT_PROPERTY(polarFinish, ParticleEffectEntityItem::DEFAULT_POLAR_FINISH), @@ -384,7 +384,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_SPEED, emitSpeed); CHECK_PROPERTY_CHANGE(PROP_SPEED_SPREAD, speedSpread); CHECK_PROPERTY_CHANGE(PROP_EMIT_ORIENTATION, emitOrientation); - CHECK_PROPERTY_CHANGE(PROP_EMIT_RADIUS, emitRadius); + CHECK_PROPERTY_CHANGE(PROP_EMIT_DIMENSIONS, emitDimensions); CHECK_PROPERTY_CHANGE(PROP_EMIT_RADIUS_START, emitRadiusStart); CHECK_PROPERTY_CHANGE(PROP_POLAR_START, polarStart); CHECK_PROPERTY_CHANGE(PROP_POLAR_FINISH, polarFinish); @@ -510,7 +510,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(emitSpeed); COPY_PROPERTY_TO_QSCRIPTVALUE(speedSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(emitOrientation); - COPY_PROPERTY_TO_QSCRIPTVALUE(emitRadius); + COPY_PROPERTY_TO_QSCRIPTVALUE(emitDimensions); COPY_PROPERTY_TO_QSCRIPTVALUE(emitRadiusStart); COPY_PROPERTY_TO_QSCRIPTVALUE(polarStart); COPY_PROPERTY_TO_QSCRIPTVALUE(polarFinish); @@ -656,7 +656,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); COPY_PROPERTY_FROM_QSCRIPTVALUE(speedSpread, float, setSpeedSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitOrientation, glmQuat, setEmitOrientation); - COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRadius, glmVec3, setEmitRadius); + COPY_PROPERTY_FROM_QSCRIPTVALUE(emitDimensions, glmVec3, setEmitDimensions); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRadiusStart, float, setEmitRadiusStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(polarStart, float, setPolarStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(polarFinish, float, setPolarFinish); @@ -916,7 +916,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, properties.getEmitSpeed()); APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, properties.getSpeedSpread()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, properties.getEmitOrientation()); - APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS, properties.getEmitRadius()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, properties.getEmitDimensions()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, properties.getEmitRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_POLAR_START, properties.getPolarStart()); APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, properties.getPolarFinish()); @@ -1207,7 +1207,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS, glm::vec3, setEmitRadius); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_START, float, setPolarStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_FINISH, float, setPolarFinish); @@ -1363,7 +1363,7 @@ void EntityItemProperties::markAllChanged() { _emitSpeedChanged = true; _speedSpreadChanged = true; _emitOrientationChanged = true; - _emitRadiusChanged = true; + _emitDimensionsChanged = true; _emitRadiusStartChanged = true; _polarStartChanged = true; _polarFinishChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 8e899d7651..30d63b407c 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -141,7 +141,7 @@ public: DEFINE_PROPERTY(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, float); DEFINE_PROPERTY(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, float); DEFINE_PROPERTY_REF(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, glm::quat); - DEFINE_PROPERTY_REF(PROP_EMIT_RADIUS, EmitRadius, emitRadius, glm::vec3); + DEFINE_PROPERTY_REF(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, glm::vec3); DEFINE_PROPERTY(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float); DEFINE_PROPERTY(PROP_POLAR_START, PolarStart, polarStart, float); DEFINE_PROPERTY(PROP_POLAR_FINISH, PolarFinish, polarFinish, float); @@ -345,7 +345,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitSpeed, emitSpeed, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, SpeedSpread, speedSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitOrientation, emitOrientation, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRadius, emitRadius, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitDimensions, emitDimensions, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRadiusStart, emitRadiusStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, PolarStart, polarStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, PolarFinish, polarFinish, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 741cfabf92..b3e20110c4 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -163,7 +163,7 @@ enum EntityPropertyList { PROP_EMIT_SPEED, PROP_SPEED_SPREAD, PROP_EMIT_ORIENTATION, - PROP_EMIT_RADIUS, + PROP_EMIT_DIMENSIONS, PROP_EMIT_RADIUS_START, PROP_POLAR_START, PROP_POLAR_FINISH, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 59a8e126cf..7bb584fdcf 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -61,8 +61,8 @@ const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_SPEED = 5.0f; const float ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD = 1.0f; const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); // Vertical -const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS = glm::vec3(0.0f, 0.0f, 0.0f); // Emit from point -const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitRadius > 0) +const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_DIMENSIONS = glm::vec3(0.0f, 0.0f, 0.0f); // Emit from point +const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitDimensions > 0) const float ParticleEffectEntityItem::DEFAULT_POLAR_START = 0.0f; // Emit along z-axis const float ParticleEffectEntityItem::DEFAULT_POLAR_FINISH = 0.0f; // "" const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) @@ -130,8 +130,8 @@ void ParticleEffectEntityItem::setEmitOrientation(const glm::quat& emitOrientati } -void ParticleEffectEntityItem::setEmitRadius(const glm::vec3& emitRadius) { - _emitRadius = emitRadius; +void ParticleEffectEntityItem::setEmitDimensions(const glm::vec3& emitDimensions) { + _emitDimensions = emitDimensions; computeAndUpdateDimensions(); } @@ -153,7 +153,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() { glm::vec3 maxVelocity = glm::abs(velocity) + velocitySpread; glm::vec3 maxAccleration = glm::abs(_acceleration) + _accelerationSpread; - glm::vec3 maxDistance = _emitRadius + time * maxVelocity + (0.5f * time * time) * maxAccleration; + glm::vec3 maxDistance = 0.5f * _emitDimensions + time * maxVelocity + (0.5f * time * time) * maxAccleration; float maxDistanceValue = std::max(maxDistance.x, std::max(maxDistance.y, maxDistance.z)); @@ -180,7 +180,7 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitSpeed, getEmitSpeed); COPY_ENTITY_PROPERTY_TO_PROPERTIES(speedSpread, getSpeedSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitOrientation, getEmitOrientation); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRadius, getEmitRadius); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitDimensions, getEmitDimensions); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRadiusStart, getEmitRadiusStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(polarStart, getPolarStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(polarFinish, getPolarFinish); @@ -220,7 +220,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitSpeed, setEmitSpeed); SET_ENTITY_PROPERTY_FROM_PROPERTIES(speedSpread, setSpeedSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitOrientation, setEmitOrientation); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRadius, setEmitRadius); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitDimensions, setEmitDimensions); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRadiusStart, setEmitRadiusStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(polarStart, setPolarStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(polarFinish, setPolarFinish); @@ -330,7 +330,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); - READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS, glm::vec3, setEmitRadius); + READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart); READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish); @@ -372,7 +372,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_EMIT_SPEED; requestedProperties += PROP_SPEED_SPREAD; requestedProperties += PROP_EMIT_ORIENTATION; - requestedProperties += PROP_EMIT_RADIUS; + requestedProperties += PROP_EMIT_DIMENSIONS; requestedProperties += PROP_EMIT_RADIUS_START; requestedProperties += PROP_POLAR_START; requestedProperties += PROP_POLAR_FINISH; @@ -417,7 +417,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, getEmitSpeed()); APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, getSpeedSpread()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, getEmitOrientation()); - APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS, getEmitRadius()); + APPEND_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, getEmitDimensions()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, getEmitRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_POLAR_START, getPolarStart()); APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, getPolarFinish()); @@ -689,7 +689,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; - } else if (_emitRadius == glm::vec3()) { + } else if (_emitDimensions == glm::vec3()) { // Emit around point float elevation = asin(2.0f * randFloat() - 1.0f); // Distribute points evenly over surface glm::vec3 emitDirection = _emitOrientation * fromSpherical(elevation, randFloat() * TWO_PI); @@ -705,14 +705,15 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { float azimuth = (2.0f * randFloat() - 1.0f) * PI; // TODO: Sort out ellipsoid equations to distribute completely evenly over surface. - float x = _emitRadius.x * cos(elevation) * cos(azimuth); - float y = _emitRadius.y * cos(elevation) * sin(azimuth); - float z = _emitRadius.z * sin(elevation); + glm::vec3 radiuses = 0.5f * _emitDimensions; + float x = radiuses.x * cos(elevation) * cos(azimuth); + float y = radiuses.y * cos(elevation) * sin(azimuth); + float z = radiuses.z * sin(elevation); glm::vec3 emitPosition = glm::vec3(x, y, z); glm::vec3 emitDirection = glm::normalize(glm::vec3( - x / (_emitRadius.x * _emitRadius.x), - y / (_emitRadius.y * _emitRadius.y), - z / (_emitRadius.z * _emitRadius.z) + x / (radiuses.x * radiuses.x), + y / (radiuses.y * radiuses.y), + z / (radiuses.z * radiuses.z) )); _particlePositions[i] = getPosition() + _emitOrientation * emitPosition; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index d5ec4eb587..9d39c4cd10 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -140,9 +140,9 @@ public: void setEmitOrientation(const glm::quat& emitOrientation); const glm::quat& getEmitOrientation() const { return _emitOrientation; } - static const glm::vec3 DEFAULT_EMIT_RADIUS; - void setEmitRadius(const glm::vec3& emitRadius); - const glm::vec3& getEmitRadius() const { return _emitRadius; } + static const glm::vec3 DEFAULT_EMIT_DIMENSIONS; + void setEmitDimensions(const glm::vec3& emitDimensions); + const glm::vec3& getEmitDimensions() const { return _emitDimensions; } static const float DEFAULT_EMIT_RADIUS_START; void setEmitRadiusStart(float emitRadiusStart) { _emitRadiusStart = emitRadiusStart; } @@ -233,7 +233,7 @@ protected: float _emitSpeed = DEFAULT_EMIT_SPEED; float _speedSpread = DEFAULT_SPEED_SPREAD; glm::quat _emitOrientation = DEFAULT_EMIT_ORIENTATION; - glm::vec3 _emitRadius = DEFAULT_EMIT_RADIUS; + glm::vec3 _emitDimensions = DEFAULT_EMIT_DIMENSIONS; float _emitRadiusStart = DEFAULT_EMIT_RADIUS_START; float _polarStart = DEFAULT_POLAR_START; float _polarFinish = DEFAULT_POLAR_FINISH; From 9e2b5b75b641cd214a0c0c2c7af2b25adb82162e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2015 22:40:49 -0700 Subject: [PATCH 015/418] Make able to emit in specified range of directions Controlled by polar and azimuth start and finish angles, around point or from specified part of spheroid surface. --- examples/example/entities/particlesTest.js | 49 ++++++++++---- .../entities/src/ParticleEffectEntityItem.cpp | 66 +++++++++++-------- 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 7fe98e3c28..3f07d9fae5 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -22,13 +22,15 @@ particleExample = -1, PARTICLE_RADIUS = 0.04, SLOW_EMIT_RATE = 2.0, + HALF_EMIT_RATE = 50.0, FAST_EMIT_RATE = 100.0, - SLOW_EMIT_SPEED = 0.05, + SLOW_EMIT_SPEED = 0.025, FAST_EMIT_SPEED = 1.0, GRAVITY_EMIT_ACCELERATON = { x: 0.0, y: -0.3, z: 0.0 }, ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 }, PI = 3.141593, - NUM_PARTICLE_EXAMPLES = 13; + DEG_TO_RAD = PI / 180.0, + NUM_PARTICLE_EXAMPLES = 17; function onClickDownOnEntity(entityID) { if (entityID === box || entityID === sphere || entityID === particles) { @@ -116,23 +118,24 @@ }); break; case 10: - print("Emit in all directions from point"); + print("Emit in a spread beam"); Entities.editEntity(particles, { colorStart: { red: 255, green: 255, blue: 255 }, colorFinish: { red: 255, green: 255, blue: 255 }, + alphaFinish: 0.0, emitRate: FAST_EMIT_RATE, + polarFinish: 2.0 * DEG_TO_RAD + }); + break; + case 11: + print("Emit in all directions from point"); + Entities.editEntity(particles, { emitSpeed: SLOW_EMIT_SPEED, emitAcceleration: ZERO_EMIT_ACCELERATON, polarFinish: PI }); - Entities.editEntity(box, { - visible: false - }); - Entities.editEntity(sphere, { - visible: true - }); break; - case 11: + case 12: print("Emit from sphere surface"); Entities.editEntity(particles, { colorStart: { red: 255, green: 255, blue: 255 }, @@ -147,15 +150,39 @@ visible: true }); break; - case 12: + case 13: + print("Emit from hemisphere of sphere surface"); + Entities.editEntity(particles, { + polarFinish: PI / 2.0 + }); + break; + case 14: + print("Emit from equator of sphere surface"); + Entities.editEntity(particles, { + polarStart: PI / 2.0, + emitRate: HALF_EMIT_RATE + }); + break; + case 15: + print("Emit from half equator of sphere surface"); + Entities.editEntity(particles, { + azimuthStart: -PI / 2.0, + azimuthFinish: PI / 2.0 + }); + break; + case 16: print("Stop emitting"); Entities.editEntity(particles, { emitDimensions: pointDimensions, emitOrientation: verticalOrientation, + alphaFinish: 1.0, emitRate: SLOW_EMIT_RATE, emitSpeed: FAST_EMIT_SPEED, emitAcceleration: GRAVITY_EMIT_ACCELERATON, + polarStart: 0.0, polarFinish: 0.0, + azimuthStart: -PI, + azimuthFinish: PI, animationIsPlaying: false }); Entities.editEntity(box, { diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 7bb584fdcf..42de5bd7e4 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -66,7 +66,7 @@ const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit const float ParticleEffectEntityItem::DEFAULT_POLAR_START = 0.0f; // Emit along z-axis const float ParticleEffectEntityItem::DEFAULT_POLAR_FINISH = 0.0f; // "" const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) -const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH = -PI; // "" +const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH = PI; // "" const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; @@ -689,34 +689,46 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; - } else if (_emitDimensions == glm::vec3()) { - // Emit around point - float elevation = asin(2.0f * randFloat() - 1.0f); // Distribute points evenly over surface - glm::vec3 emitDirection = _emitOrientation * fromSpherical(elevation, randFloat() * TWO_PI); - - _particlePositions[i] = getPosition(); - _particleVelocities[i] = - (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; - } else { - // Emit from ellipsoid - float elevation = asin(2.0f * randFloat() - 1.0f); // Distribute points approximately evenly over surface - float azimuth = (2.0f * randFloat() - 1.0f) * PI; - // TODO: Sort out ellipsoid equations to distribute completely evenly over surface. - - glm::vec3 radiuses = 0.5f * _emitDimensions; - float x = radiuses.x * cos(elevation) * cos(azimuth); - float y = radiuses.y * cos(elevation) * sin(azimuth); - float z = radiuses.z * sin(elevation); - glm::vec3 emitPosition = glm::vec3(x, y, z); - glm::vec3 emitDirection = glm::normalize(glm::vec3( - x / (radiuses.x * radiuses.x), - y / (radiuses.y * radiuses.y), - z / (radiuses.z * radiuses.z) - )); + // Emit around point or from ellipsoid + // - Distribute directions evenly around point + // - Distribute points relatively evenly over ellipsoid surface + + float elevationMinZ = sin(PI_OVER_TWO - _polarFinish); + float elevationMaxZ = sin(PI_OVER_TWO - _polarStart); + float elevation = asin(elevationMinZ + (elevationMaxZ - elevationMinZ) * randFloat()); + + float azimuth; + if (_azimuthFinish >= _azimuthStart) { + azimuth = _azimuthStart + (_azimuthFinish - _azimuthStart) * randFloat(); + } else { + azimuth = _azimuthStart + (2.0 * PI + _azimuthFinish - _azimuthStart) * randFloat(); + } + + glm::vec3 emitDirection; + + if (_emitDimensions == glm::vec3()) { + // Point + emitDirection = _emitOrientation * fromSpherical(elevation, azimuth); + + _particlePositions[i] = getPosition(); + + } else { + // Ellipsoid + glm::vec3 radiuses = 0.5f * _emitDimensions; + float x = radiuses.x * cos(elevation) * cos(azimuth); + float y = radiuses.y * cos(elevation) * sin(azimuth); + float z = radiuses.z * sin(elevation); + glm::vec3 emitPosition = glm::vec3(x, y, z); + emitDirection = glm::normalize(glm::vec3( + x / (radiuses.x * radiuses.x), + y / (radiuses.y * radiuses.y), + z / (radiuses.z * radiuses.z) + )); + + _particlePositions[i] = getPosition() + _emitOrientation * emitPosition; + } - _particlePositions[i] = getPosition() + _emitOrientation * emitPosition; _particleVelocities[i] = (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; From 8634b59914151dd623a9a79b630ead58bf7e7e99 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 17 Sep 2015 23:49:57 -0700 Subject: [PATCH 016/418] Make able to emit from within portion of ellipsoid volume --- examples/example/entities/particlesTest.js | 14 +++++++++++++- .../entities/src/ParticleEffectEntityItem.cpp | 10 +++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 3f07d9fae5..8548ce5f86 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -30,7 +30,7 @@ ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 }, PI = 3.141593, DEG_TO_RAD = PI / 180.0, - NUM_PARTICLE_EXAMPLES = 17; + NUM_PARTICLE_EXAMPLES = 18; function onClickDownOnEntity(entityID) { if (entityID === box || entityID === sphere || entityID === particles) { @@ -171,6 +171,18 @@ }); break; case 16: + print("Emit within quarter of sphere volume"); + Entities.editEntity(particles, { + polarStart: 0.0, + polarFinish: PI / 2.0, + azimuthStart: 0, + azimuthFinish: PI / 2.0, + emitRadiusStart: 0.0, + alphaFinish: 1.0, + emitSpeed: 0.0 + }); + break; + case 17: print("Stop emitting"); Entities.editEntity(particles, { emitDimensions: pointDimensions, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 42de5bd7e4..46b8e844dd 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -693,6 +693,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { // Emit around point or from ellipsoid // - Distribute directions evenly around point // - Distribute points relatively evenly over ellipsoid surface + // - Distribute points relatively evenly within ellipsoid volume float elevationMinZ = sin(PI_OVER_TWO - _polarFinish); float elevationMaxZ = sin(PI_OVER_TWO - _polarStart); @@ -715,7 +716,14 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } else { // Ellipsoid - glm::vec3 radiuses = 0.5f * _emitDimensions; + float radiusScale = 1.0f; + if (_emitRadiusStart < 1.0f) { + float emitRadiusStart = glm::max(_emitRadiusStart, EPSILON); // Avoid math complications at center + float randRadius = emitRadiusStart + (1.0f - emitRadiusStart) * randFloat(); + radiusScale = 1.0f - std::pow(1.0f - randRadius, 3); + } + + glm::vec3 radiuses = radiusScale * 0.5f * _emitDimensions; float x = radiuses.x * cos(elevation) * cos(azimuth); float y = radiuses.y * cos(elevation) * sin(azimuth); float z = radiuses.z * sin(elevation); From d6377ee6bb1f1960a3c97b6340e3c08f167ba185 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 10:55:29 -0700 Subject: [PATCH 017/418] Added basketball to master reset script --- examples/toybox/masterResetEntity.js | 50 +++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 964070bd90..eef5af50e3 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -25,6 +25,12 @@ function createAllToys() { y: 495.55, z: 503.77 }); + + createBasketBall({ + x: 548.1, + y: 497, + z: 504.6 + }); } function deleteAllToys() { @@ -39,6 +45,42 @@ function deleteAllToys() { }) } +function createBasketBall(position) { + + var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: position, + collisionsWillMove: true, + shapeType: "sphere", + name: "basketball", + dimensions: { + x: 0.25, + y: 0.26, + z: 0.25 + }, + gravity: { + x: 0, + y: -7, + z: 0 + }, + restitution: 10, + linearDamping: 0.0, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + +} + function createSprayCan(position) { var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; @@ -47,7 +89,7 @@ function createSprayCan(position) { type: "Model", name: "spraycan", modelURL: modelURL, - position: position , + position: position, rotation: { x: 0, y: 0, @@ -74,9 +116,9 @@ function createSprayCan(position) { } }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } From 6e4b838bf9c97fba4dfae8abe4f187369bd263f1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 10:59:28 -0700 Subject: [PATCH 018/418] added collision sound to bbal --- examples/toybox/masterResetEntity.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index eef5af50e3..b4c8f370f9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -72,7 +72,8 @@ function createBasketBall(position) { x: 0, y: -.01, z: 0 - } + }, + collisionSoundURL : "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); setEntityCustomData(resetKey, entity, { From 65722dc87036f4215b664daf3e38ac097d8763a3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 11:01:33 -0700 Subject: [PATCH 019/418] Removed master spawner as its no longer needed --- examples/toybox/masterResetEntitySpawner.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 examples/toybox/masterResetEntitySpawner.js diff --git a/examples/toybox/masterResetEntitySpawner.js b/examples/toybox/masterResetEntitySpawner.js deleted file mode 100644 index 8938595d7f..0000000000 --- a/examples/toybox/masterResetEntitySpawner.js +++ /dev/null @@ -1,19 +0,0 @@ -var scriptURL = Script.resolvePath("masterResetEntity.js?v1" + Math.random()); - -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1, Quat.getFront(Camera.getOrientation()))); - -var resetEntity = Entities.addEntity({ - type: "Box", - dimensions: {x: .3, y: 0.3, z: 0.3}, - position: center, - color: {red: 100, green: 10, blue: 100}, - script: scriptURL -}); - - - -function cleanup() { - Entities.deleteEntity(resetEntity); -} - -Script.scriptEnding.connect(cleanup); \ No newline at end of file From 8ada3dec6e335af6e5ff6d59466af12af5fd93d5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 11:29:16 -0700 Subject: [PATCH 020/418] Adding doll in --- examples/toybox/masterResetEntity.js | 42 ++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index b4c8f370f9..c0c6e31287 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -31,6 +31,12 @@ function createAllToys() { y: 497, z: 504.6 }); + + createDoll({ + x: 545.9, + y: 496, + z: 506.2 + }) } function deleteAllToys() { @@ -57,7 +63,7 @@ function createBasketBall(position) { shapeType: "sphere", name: "basketball", dimensions: { - x: 0.25, + x: 0.25, y: 0.26, z: 0.25 }, @@ -73,7 +79,7 @@ function createBasketBall(position) { y: -.01, z: 0 }, - collisionSoundURL : "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); setEntityCustomData(resetKey, entity, { @@ -82,6 +88,38 @@ function createBasketBall(position) { } +function createDoll(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + + var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + + var entity = Entities.addEntity({ + type: "Model", + name: "doll", + modelURL: modelURL, + position: position, + shapeType: 'box', + dimensions: desiredDimensions, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -.1, + z: 0 + }, + collisionsWillMove: true + }); + + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +} + function createSprayCan(position) { var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; From 68874eed964cce5d43d9853dfe7a340d1b4a23b3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 18 Sep 2015 11:34:26 -0700 Subject: [PATCH 021/418] Update particle scripts --- examples/entityScripts/sprayPaintCan.js | 14 +++++++------- examples/fireworks.js | 11 ++++------- examples/particleDance.js | 10 ++++------ examples/particles.js | 7 +++++-- examples/toys/grenade.js | 8 ++++---- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js index 4407140184..fb90a8f447 100644 --- a/examples/entityScripts/sprayPaintCan.js +++ b/examples/entityScripts/sprayPaintCan.js @@ -83,19 +83,18 @@ lastFrame: 10000, running: true }); + var PI = 3.141593; + var DEG_TO_RAD = PI / 180.0; this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, position: this.properties.position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitVelocity: ZERO_VEC, + emitSpeed: 0, + speedSpread: 0.02, + polarFinish: 2 * DEG_TO_RAD, emitAcceleration: ZERO_VEC, - velocitySpread: { - x: .02, - y: .02, - z: 0.02 - }, emitRate: 100, particleRadius: 0.01, color: { @@ -132,7 +131,8 @@ position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) Entities.editEntity(self.paintStream, { position: position, - emitVelocity: Vec3.multiply(forwardVec, 4) + emitOrientation: forwardVec, + emitSpeed: 4 }); //Now check for an intersection with an entity diff --git a/examples/fireworks.js b/examples/fireworks.js index 621931ee36..3485b1687f 100644 --- a/examples/fireworks.js +++ b/examples/fireworks.js @@ -101,7 +101,6 @@ Rocket = function(point, colorPalette) { this.burst = false; this.emitRate = randInt(80, 120); - this.emitStrength = randInt(5.0, 7.0); this.rocket = Entities.addEntity({ type: "Sphere", @@ -163,6 +162,9 @@ Rocket.prototype.explode = function(position) { }); var colorIndex = 0; + var PI = 3.141593; + var DEG_TO_RAD = PI / 180.0; + for (var i = 0; i < NUM_BURSTS; ++i) { var color = this.colors[colorIndex]; print(JSON.stringify(color)); @@ -172,12 +174,7 @@ Rocket.prototype.explode = function(position) { position: position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: this.emitRate, - emitStrength: this.emitStrength, - emitDirection: { - x: Math.pow(-1, i) * randFloat(0.0, 1.4), - y: 1.0, - z: 0.0 - }, + polarFinish: 25 * DEG_TO_RAD, color: color, lifespan: 1.0, visible: true, diff --git a/examples/particleDance.js b/examples/particleDance.js index e920fcfa41..6b1f84bb8e 100644 --- a/examples/particleDance.js +++ b/examples/particleDance.js @@ -6,6 +6,9 @@ var AUDIO_RANGE = 0.5 * RANGE; var DIST_BETWEEN_BURSTS = 1.0; + var PI = 3.141593; + var DEG_TO_RAD = PI / 180.0; + var LOUDNESS_RADIUS_RATIO = 10; var TEXTURE_PATH = 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png'; @@ -86,12 +89,7 @@ position: this.point, textures: TEXTURE_PATH, emitRate: this.emitRate, - emitStrength: this.emitStrength, - emitDirection: { - x: Math.pow(-1, i) * randFloat(0.0, 0.4), - y: 1.0, - z: 0.0 - }, + polarFinish: 25 * DEG_TO_RAD, color: color, lifespan: 1.0, visible: true, diff --git a/examples/particles.js b/examples/particles.js index ad232dd781..def21704d1 100644 --- a/examples/particles.js +++ b/examples/particles.js @@ -35,13 +35,16 @@ firstFrame: 0, lastFrame: 30, loop: true }); + var PI = 3.141593; + var DEG_TO_RAD = PI / 180.0; this.entity = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, position: spawnPoint, dimensions: {x: 2, y: 2, z: 2}, - emitVelocity: {x: 0, y: 5, z: 0}, - velocitySpread: {x: 2, y: 0, z: 2}, + emitSpeed: 5, + speedSpread: 2, + polarFinish: 30 * DEG_TO_RAD, emitAcceleration: {x: 0, y: -9.8, z: 0}, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", color: color, diff --git a/examples/toys/grenade.js b/examples/toys/grenade.js index b2dfebb888..c6a9c5bdeb 100644 --- a/examples/toys/grenade.js +++ b/examples/toys/grenade.js @@ -45,6 +45,8 @@ var explodeAnimationSettings = JSON.stringify({ var GRAVITY = -9.8; var TIME_TO_EXPLODE = 2500; var DISTANCE_IN_FRONT_OF_ME = 1.0; +var PI = 3.141593; +var DEG_TO_RAD = PI / 180.0; function makeGrenade() { var position = Vec3.sum(MyAvatar.position, @@ -87,8 +89,7 @@ function update() { position: newProperties.position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: 100, - emitStrength: 2.0, - emitDirection: { x: 0.0, y: 1.0, z: 0.0 }, + polarFinish: 25 * DEG_TO_RAD, color: { red: 200, green: 0, blue: 0 }, lifespan: 10.0, visible: true, @@ -145,8 +146,7 @@ function boom() { position: properties.position, textures: 'https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png', emitRate: 200, - emitStrength: 3.0, - emitDirection: { x: 0.0, y: 1.0, z: 0.0 }, + polarFinish: 25 * DEG_TO_RAD, color: { red: 255, green: 255, blue: 0 }, lifespan: 2.0, visible: true, From 767407af9c0e71fab9c5fcc9366a8a8568011294 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 18 Sep 2015 11:46:44 -0700 Subject: [PATCH 022/418] Merging and cleaning shaders --- libraries/render-utils/src/DeferredBufferWrite.slh | 1 + libraries/render-utils/src/DeferredGlobalLight.slh | 11 +++-------- libraries/render-utils/src/model_lightmap.slf | 2 +- .../render-utils/src/model_lightmap_normal_map.slf | 10 +--------- .../src/model_lightmap_normal_specular_map.slf | 2 +- .../render-utils/src/model_lightmap_specular_map.slf | 2 +- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 8666a80386..b9b0198ba5 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -60,6 +60,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 s } _fragColor0 = vec4(diffuse.rgb, alpha); + //_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); _fragColor1 = vec4(bestFitNormal(normal), 0.5); _fragColor2 = vec4(emissive, shininess / 128.0); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 5f32bb5fe6..9f29a25cf0 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -135,7 +135,6 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi } <@endfunc@> - <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { @@ -148,22 +147,18 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, // it should be just 0, but we have innacurracy so we need to overshoot const float PERPENDICULAR_THRESHOLD = -0.005; float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); + //float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); // evaluate the shadow test but only relevant for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - - // lightAttenuation *= (abs(normalMapContrib) * max(0, diffuseDot) + (1.0 - abs(normalMapContrib))); - lightAttenuation *= (abs(normalMapContrib) * max(0, diffuseDot)); // diffuse light is the lightmap dimmed by shadow - vec3 diffuseLight = lightAttenuation * lightmap.rgb; + vec3 diffuseLight = lightAttenuation * lightmap; // ambient is a tiny percentage of the lightmap and only when in the shadow vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); - // return normal; - return diffuse * (ambientLight + diffuseLight); - // return lightmap.rgb; + return diffuse * (ambientLight + diffuseLight); } <@endfunc@> diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 02598fdb59..ab92d2bf4c 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -41,5 +41,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb * _color, getMaterialSpecular(mat), getMaterialShininess(mat), - vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 1a22343958..78c802be51 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -39,7 +39,6 @@ void main(void) { vec3 normalizedTangent = normalize(_tangent); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5); - vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); @@ -47,13 +46,6 @@ void main(void) { vec4 diffuse = texture(diffuseMap, _texCoord0); vec4 emissive = texture(emissiveMap, _texCoord1); - // WE have lightmap AND normal map so we are going to alter the lighting intensity - // from the lightmap with the dot product between the surface normal and the normal map - // Why will you ask? because we want to see something out of the normal map and since - // the lighting from the lightmap doesnt't give a light direction, we just hack one... - vec4 lightIntensity = vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, - 0.5 * dot(localNormal, vec3(0.0, 1.0, 0.0)) + 0.5 ); - Material mat = getMaterial(); packDeferredFragmentLightmap( @@ -62,5 +54,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb * _color, getMaterialSpecular(mat), getMaterialShininess(mat), - lightIntensity); + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index 83423ac3c7..1b7416baa5 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -58,5 +58,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb * _color, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), - vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 83f232c958..efdfcd6be9 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -46,5 +46,5 @@ void main(void) { getMaterialDiffuse(mat) * diffuse.rgb * _color, specular, // no use of getMaterialSpecular(mat) getMaterialShininess(mat), - vec4(vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb, 0.0)); + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } From 5f5cc3dbafb55c450b966c4772ad79440d604e05 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 18 Sep 2015 11:51:28 -0700 Subject: [PATCH 023/418] fix typos --- libraries/render-utils/src/DeferredGlobalLight.slh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 9f29a25cf0..16cd272da5 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -147,18 +147,17 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, // it should be just 0, but we have innacurracy so we need to overshoot const float PERPENDICULAR_THRESHOLD = -0.005; float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - //float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); + //float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); // evaluate the shadow test but only relevant for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - // diffuse light is the lightmap dimmed by shadow vec3 diffuseLight = lightAttenuation * lightmap; // ambient is a tiny percentage of the lightmap and only when in the shadow vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); - return diffuse * (ambientLight + diffuseLight); + return diffuse * (ambientLight + diffuseLight); } <@endfunc@> From 64cf8590ebccddac204b31d2645e3ae5dcd62020 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 18 Sep 2015 11:51:58 -0700 Subject: [PATCH 024/418] fix typos --- libraries/render-utils/src/DeferredGlobalLight.slh | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 16cd272da5..983b8002f7 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -148,7 +148,6 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, const float PERPENDICULAR_THRESHOLD = -0.005; float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); //float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - // evaluate the shadow test but only relevant for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; // diffuse light is the lightmap dimmed by shadow From 86dfa6f590c3feb6784ea33930c8ab892717c10f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 12:35:49 -0700 Subject: [PATCH 025/418] 2 sizes for blocks --- examples/toybox/masterResetEntity.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index c0c6e31287..695730b49d 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -163,12 +163,11 @@ function createSprayCan(position) { function createBlocks(position) { var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - var BASE_DIMENSIONS = Vec3.multiply({ - x: 0.2, - y: 0.1, - z: 0.8 - }, 0.2); - var NUM_BLOCKS = 4; + var dimensionsArray = [ + {x: .1, y: 0.05, z: 0.25}, + {x: 0.06, y: 0.04, z: 0.28} + ]; + var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { var entity = Entities.addEntity({ @@ -181,11 +180,7 @@ function createBlocks(position) { }), shapeType: 'box', name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, { - x: Math.random() / 10, - y: Math.random() / 10, - z: Math.random() / 10 - }), + dimensions: dimensionsArray[randInt(0, dimensionsArray.length)], collisionsWillMove: true, gravity: { x: 0, @@ -210,4 +205,12 @@ function cleanup() { deleteAllToys(); } -Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); + +function randFloat(low, high) { + return low + Math.random() * (high - low); +} + +function randInt(low, high) { + return Math.floor(randFloat(low, high)); +} From ec146069b14e97e86f80de360935bb6d483f5d82 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 18 Sep 2015 13:06:18 -0700 Subject: [PATCH 026/418] Reuse old property enum slots --- libraries/entities/src/EntityPropertyFlags.h | 8 +++----- libraries/entities/src/ParticleEffectEntityItem.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index b3e20110c4..2298e41bde 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -96,7 +96,7 @@ enum EntityPropertyList { PROP_MAX_PARTICLES, PROP_LIFESPAN, PROP_EMIT_RATE, - PROP_EMIT_VELOCITY, + PROP_EMIT_SPEED, PROP_EMIT_STRENGTH, PROP_EMIT_ACCELERATION, PROP_PARTICLE_RADIUS, @@ -136,7 +136,7 @@ enum EntityPropertyList { PROP_STROKE_WIDTHS, // used by particles - PROP_VELOCITY_SPREAD, + PROP_SPEED_SPREAD, PROP_ACCELERATION_SPREAD, PROP_X_N_NEIGHBOR_ID, // used by PolyVox @@ -160,8 +160,6 @@ enum EntityPropertyList { PROP_ALPHA_SPREAD, PROP_ALPHA_START, PROP_ALPHA_FINISH, - PROP_EMIT_SPEED, - PROP_SPEED_SPREAD, PROP_EMIT_ORIENTATION, PROP_EMIT_DIMENSIONS, PROP_EMIT_RADIUS_START, @@ -202,7 +200,7 @@ enum EntityPropertyList { PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES, PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN, PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE, - PROP_ATMOSPHERE_MIE_SCATTERING = PROP_EMIT_VELOCITY, + PROP_ATMOSPHERE_MIE_SCATTERING = PROP_EMIT_SPEED, PROP_ATMOSPHERE_RAYLEIGH_SCATTERING = PROP_EMIT_STRENGTH, PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS = PROP_EMIT_ACCELERATION, PROP_ATMOSPHERE_HAS_STARS = PROP_PARTICLE_RADIUS, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 46b8e844dd..eb769dff3b 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -289,7 +289,8 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { - SKIP_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, glm::vec3); + // OLD PROP_EMIT_VELOCITY FAKEOUT + SKIP_ENTITY_PROPERTY(PROP_EMIT_SPEED, glm::vec3); } if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_MODIFICATIONS) { @@ -298,7 +299,8 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { - SKIP_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, glm::vec3); + // OLD PROP_VELOCITY_SPREAD FAKEOUT + SKIP_ENTITY_PROPERTY(PROP_SPEED_SPREAD, glm::vec3); } } else { // EMIT_ACCELERATION FAKEOUT From dd3f1301e651095514585ed41865695ad74a9846 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 14:36:41 -0700 Subject: [PATCH 027/418] Blocks are now multi colored --- examples/toybox/masterResetEntity.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 695730b49d..68510c1dfb 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -162,7 +162,8 @@ function createSprayCan(position) { } function createBlocks(position) { - var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" + var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; var dimensionsArray = [ {x: .1, y: 0.05, z: 0.25}, {x: 0.06, y: 0.04, z: 0.28} @@ -170,12 +171,13 @@ function createBlocks(position) { var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { + var modelURL = baseURL + modelURLs[randInt(0, modelURLs.length)]; var entity = Entities.addEntity({ type: "Model", - modelURL: modelUrl, + modelURL: modelURL, position: Vec3.sum(position, { x: 0, - y: i / 5, + y: i / 10, z: 0 }), shapeType: 'box', From 60ba6e174fa675a4b09e929d020e2658dc987f84 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 18 Sep 2015 16:44:20 -0700 Subject: [PATCH 028/418] Typo --- examples/example/entities/particlesTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 8548ce5f86..bfa4a47ffb 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -171,7 +171,7 @@ }); break; case 16: - print("Emit within quarter of sphere volume"); + print("Emit within eighth of sphere volume"); Entities.editEntity(particles, { polarStart: 0.0, polarFinish: PI / 2.0, From de14fc64f60ccb2ec4493a5510965f9e901f2df8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:17:55 -0700 Subject: [PATCH 029/418] screaming on grab. Need to get release working --- examples/toybox/entityScripts/doll.js | 72 +++++++++++++++++++++++++++ examples/toybox/masterResetEntity.js | 18 ++++++- 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 examples/toybox/entityScripts/doll.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js new file mode 100644 index 0000000000..04a5e4f7eb --- /dev/null +++ b/examples/toybox/entityScripts/doll.js @@ -0,0 +1,72 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Brad Hefta-Gaub on 9/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + Doll = function() { + _this = this; + var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" + this.screamSound = SoundCache.getSound(screamSoundDirectory + "dollScream1.wav") + this.startAnimationSetting = JSON.stringify({ + running: true + }); + + this.stopAnimationSetting = JSON.stringify({ + running: false + }); + }; + + Doll.prototype = { + + + startNearGrab: function() { + print("I was just grabbed... entity:" + this.entityID); + Entities.editEntity(this.entityID, { + animationSettings: this.startAnimationSetting + }); + + var position = Entities.getEntityProperties(this.entityID, "position").position; + print("POSITIONNN " + JSON.stringify(position)) + print("SCREAM SOUND ") + Audio.playSound(this.screamSound[0], { + position: position, + volume: 0.1 + }); + + }, + + release: function() { + print("RELEASE") + Entities.editEntity(this.entityID, { + animationSettings: this.stopAnimationSetting + }); + }, + + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { + this.entityID = entityID; + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new Doll(); +}) \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 68510c1dfb..23f4b46503 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -5,6 +5,8 @@ var resetKey = "resetMe"; HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var shouldDeleteOnEndScript = false; + //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); @@ -90,14 +92,23 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; + var animationSettings = JSON.stringify({ + running: false + }); + + var scriptURL = Script.resolvePath("entityScripts/doll.js"); + // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); - var entity = Entities.addEntity({ type: "Model", name: "doll", modelURL: modelURL, + animationSettings: animationSettings, + animationURL: animationURL, + script: scriptURL, position: position, shapeType: 'box', dimensions: desiredDimensions, @@ -207,7 +218,10 @@ function cleanup() { deleteAllToys(); } -Script.scriptEnding.connect(cleanup); +if(shouldDeleteOnEndScript) { + + Script.scriptEnding.connect(cleanup); +} function randFloat(low, high) { return low + Math.random() * (high - low); From b62807011c8f774d6ab6b5717071f06e635c297d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:22:45 -0700 Subject: [PATCH 030/418] Doll screams and writhes when picked up, returns to default position when let go --- examples/toybox/entityScripts/doll.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 04a5e4f7eb..76da29a14b 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -27,6 +27,7 @@ }); this.stopAnimationSetting = JSON.stringify({ + frameIndex: 0, running: false }); }; @@ -43,14 +44,14 @@ var position = Entities.getEntityProperties(this.entityID, "position").position; print("POSITIONNN " + JSON.stringify(position)) print("SCREAM SOUND ") - Audio.playSound(this.screamSound[0], { + Audio.playSound(this.screamSound, { position: position, volume: 0.1 }); }, - release: function() { + releaseGrab: function() { print("RELEASE") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting From fb9896019400c8de908266802a53de14bb092a08 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:45:28 -0700 Subject: [PATCH 031/418] Adding wand to master script --- examples/toybox/entityScripts/wand.js | 0 examples/toybox/masterResetEntity.js | 77 +++++++++++++++++++++------ 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 examples/toybox/entityScripts/wand.js diff --git a/examples/toybox/entityScripts/wand.js b/examples/toybox/entityScripts/wand.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 23f4b46503..722705b254 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -38,7 +38,13 @@ function createAllToys() { x: 545.9, y: 496, z: 506.2 - }) + }); + + createWand({ + x: 546.48, + y: 495.63, + z: 506.25 + }); } function deleteAllToys() { @@ -53,6 +59,38 @@ function deleteAllToys() { }) } +function createWand(position) { + var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; + //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/ccf125c047426a2c481d3ee8c58a05fc6048fdde/examples/toys/bubblewand/wand.js" + + var entity = Entities.addEntity({ + name: 'Bubble Wand', + type: "Model", + modelURL: WAND_MODEL, + position: position, + gravity: { + x: 0, + y: 0, + z: 0, + }, + dimensions: { + x: 0.05, + y: 0.25, + z: 0.05 + }, + //must be enabled to be grabbable in the physics engine + collisionsWillMove: true, + compoundShapeURL: WAND_COLLISION_SHAPE, + script: scriptURL + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +} + function createBasketBall(position) { var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; @@ -93,14 +131,18 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; - var animationSettings = JSON.stringify({ + var animationSettings = JSON.stringify({ running: false }); - - var scriptURL = Script.resolvePath("entityScripts/doll.js"); - // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); - var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var scriptURL = Script.resolvePath("entityScripts/doll.js"); + // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -175,10 +217,15 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var dimensionsArray = [ - {x: .1, y: 0.05, z: 0.25}, - {x: 0.06, y: 0.04, z: 0.28} - ]; + var dimensionsArray = [{ + x: .1, + y: 0.05, + z: 0.25 + }, { + x: 0.06, + y: 0.04, + z: 0.28 + }]; var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { @@ -218,15 +265,15 @@ function cleanup() { deleteAllToys(); } -if(shouldDeleteOnEndScript) { +if (shouldDeleteOnEndScript) { - Script.scriptEnding.connect(cleanup); + Script.scriptEnding.connect(cleanup); } function randFloat(low, high) { - return low + Math.random() * (high - low); + return low + Math.random() * (high - low); } function randInt(low, high) { - return Math.floor(randFloat(low, high)); -} + return Math.floor(randFloat(low, high)); +} \ No newline at end of file From 5cd69c4f03a6ea51097eef19dee7b389a40221d0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 09:17:23 -0700 Subject: [PATCH 032/418] Added dice to master reset script --- examples/toybox/masterResetEntity.js | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 722705b254..57924fb6e2 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -41,10 +41,12 @@ function createAllToys() { }); createWand({ - x: 546.48, + x: 546.45, y: 495.63, - z: 506.25 + z: 506.18 }); + + createDice(); } function deleteAllToys() { @@ -59,6 +61,34 @@ function deleteAllToys() { }) } +function createDice() { + var diceProps = { + type: "Model", + modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", + name: "dice", + position: {x: 541.1, y: 494.94, z: 509.21 }, + dimensions: {x: 0.09, y: 0.09, z: 0.09}, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: {x: 0, y: -.01, z: 0}, + shapeType: "box", + collisionsWillMove: true + } + var dice1 = Entities.addEntity(diceProps); + + diceProps.position = {x: 540.99, y: 494.4, z: 509.08}; + + var dice2 = Entities.addEntity(diceProps); + + setEntityCustomData(resetKey, dice1, { + resetMe: true + }); + + setEntityCustomData(resetKey, dice2, { + resetMe: true + }); +} + function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; @@ -83,6 +113,8 @@ function createWand(position) { //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, + // gravity: {x: 0, y: -3.5, z: 0}, + // velocity: {x: 0, y: -0.01, z:0}, script: scriptURL }); From a71f1495e91d17d3b9e18b2e9b1da447b24c1ad6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:15:40 -0700 Subject: [PATCH 033/418] Lowered sound volume on doll, now choose between two screams --- examples/toybox/entityScripts/doll.js | 24 +++++++++++++++--------- examples/toybox/masterResetEntity.js | 3 +-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 76da29a14b..f3850d760d 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -21,7 +21,7 @@ Doll = function() { _this = this; var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSound = SoundCache.getSound(screamSoundDirectory + "dollScream1.wav") + this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ running: true }); @@ -36,25 +36,23 @@ startNearGrab: function() { - print("I was just grabbed... entity:" + this.entityID); Entities.editEntity(this.entityID, { + animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting }); var position = Entities.getEntityProperties(this.entityID, "position").position; - print("POSITIONNN " + JSON.stringify(position)) - print("SCREAM SOUND ") - Audio.playSound(this.screamSound, { + Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { position: position, - volume: 0.1 + volume: 0.01 }); }, releaseGrab: function() { - print("RELEASE") Entities.editEntity(this.entityID, { - animationSettings: this.stopAnimationSetting + animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + // animationSettings: this.stopAnimationSetting }); }, @@ -70,4 +68,12 @@ // entity scripts always need to return a newly constructed object of our type return new Doll(); -}) \ No newline at end of file +}) + +function randFloat(low, high) { + return low + Math.random() * (high - low); +} + +function randInt(low, high) { + return Math.floor(randFloat(low, high)); +} \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 57924fb6e2..0ce949562d 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -113,6 +113,7 @@ function createWand(position) { //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, + //Look into why bubble wand is going through table when gravity is enabled // gravity: {x: 0, y: -3.5, z: 0}, // velocity: {x: 0, y: -0.01, z:0}, script: scriptURL @@ -168,7 +169,6 @@ function createDoll(position) { }); var scriptURL = Script.resolvePath("entityScripts/doll.js"); - // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var naturalDimensions = { x: 1.63, @@ -199,7 +199,6 @@ function createDoll(position) { collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, { resetMe: true }); From 30198aa6f22ddf29901a94b9f48503538d4d2b10 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:22:35 -0700 Subject: [PATCH 034/418] Only play animation once for screaming doll when picked up --- examples/toybox/entityScripts/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index f3850d760d..63b4fcc43d 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -23,11 +23,11 @@ var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ - running: true + running: true, + lastFrame: 64 }); this.stopAnimationSetting = JSON.stringify({ - frameIndex: 0, running: false }); }; From 4e517b78e122acd9e681f1247314d262e5952b0a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:26:56 -0700 Subject: [PATCH 035/418] dice spawning higher so they fall onto craps table --- examples/toybox/masterResetEntity.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 0ce949562d..627927e109 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -67,7 +67,7 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541.1, y: 494.94, z: 509.21 }, + position: {x: 541.1, y: 496, z: 509.21 }, dimensions: {x: 0.09, y: 0.09, z: 0.09}, gravity: {x: 0, y: -3.5, z: 0}, velocity: {x: 0, y: -.01, z: 0}, @@ -76,7 +76,7 @@ function createDice() { } var dice1 = Entities.addEntity(diceProps); - diceProps.position = {x: 540.99, y: 494.4, z: 509.08}; + diceProps.position = {x: 540.99, y: 496, z: 509.08}; var dice2 = Entities.addEntity(diceProps); From d24df99445e8c95f0d00de55ae54a642e4ab8a18 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:51:00 -0700 Subject: [PATCH 036/418] Updated block logic to sync with desired behavior (each color block maps to a different size) --- examples/toybox/masterResetEntity.js | 95 ++++++++++++++++------------ 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 627927e109..7fbcc97f4a 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -248,47 +248,64 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var dimensionsArray = [{ - x: .1, - y: 0.05, - z: 0.25 - }, { - x: 0.06, - y: 0.04, - z: 0.28 - }]; - var NUM_BLOCKS = 12; + var blockTypes = [ + { + url: "planky_blue.fbx", + dimensions: {x: 0.05, y: 0.05, z: 0.25} + }, + { + url: "planky_green.fbx", + dimensions: {x: 0.1, y: 0.1, z: 0.25} + }, + { + url: "planky_natural.fbx", + dimensions: {x: 0.05, y: 0.05, z: 0.05} + }, + { + url: "planky_yellow.fbx", + dimensions: {x: 0.03, y: 0.05, z: 0.25} + }, + { + url: "planky_red.fbx", + dimensions: {x: 0.1, y: 0.05, z: 0.25} + }, - for (var i = 0; i < NUM_BLOCKS; i++) { - var modelURL = baseURL + modelURLs[randInt(0, modelURLs.length)]; - var entity = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: Vec3.sum(position, { - x: 0, - y: i / 10, - z: 0 - }), - shapeType: 'box', - name: "block", - dimensions: dimensionsArray[randInt(0, dimensionsArray.length)], - collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -.01, - z: 0 - } - }); - //customKey, id, data - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + ]; + var NUM_BLOCKS_PER_COLOR = 4; + + for (var i = 0; i < blockTypes.length; i++) { + for(j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + var modelURL = baseURL + blockTypes[i].url; + var entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: Vec3.sum(position, { + x: j/10, + y: i / 10, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: blockTypes[i].dimensions, + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + //customKey, id, data + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + } } } From b727256377b852244bee7ba499682a580a0aef73 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 13:05:37 -0700 Subject: [PATCH 037/418] animation of doll plays longer now to give user a chance to see it play --- examples/toybox/entityScripts/doll.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 63b4fcc43d..0f4aaf5cd7 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -24,7 +24,8 @@ this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ running: true, - lastFrame: 64 + startFrame: 0, + lastFrame: 128 }); this.stopAnimationSetting = JSON.stringify({ From 8678e07c21555c35cc05f1bd622358279de7513a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 15:45:54 -0700 Subject: [PATCH 038/418] Adding in light triggering logic --- examples/toybox/entityScripts/doll.js | 8 +- examples/toybox/entityScripts/lightSwitch.js | 97 +++++++++++++++ examples/toybox/entityScripts/wand.js | 0 examples/toybox/masterResetEntity.js | 119 +++++++++++++++---- 4 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 examples/toybox/entityScripts/lightSwitch.js delete mode 100644 examples/toybox/entityScripts/wand.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 0f4aaf5cd7..86e7fcc62c 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -1,11 +1,11 @@ // -// detectGrabExample.js -// examples/entityScripts +// doll.js +// examples/toybox/entityScripts // -// Created by Brad Hefta-Gaub on 9/3/15. +// Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// This entity script breathes movement and sound- one might even say life- into a doll. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js new file mode 100644 index 0000000000..bb80d76f57 --- /dev/null +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -0,0 +1,97 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + LightSwitch = function() { + _this = this; + + this.lightStateKey = "lightStateKey"; + this.resetKey = "resetMe"; + + }; + + LightSwitch.prototype = { + + + startNearGrab: function() { + print("TOGGLE LIGHT") + + // var position = Entities.getEntityProperties(this.entityID, "position").position; + // Audio.playSound(clickSound, { + // position: position, + // volume: 0.05 + // }); + + }, + + createLights: function() { + print("CREATE LIGHTS *******************") + this.sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.62, + y: 496.24, + z: 511.23 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, this.sconceLight1, { + resetMe: true + }); + }, + + // clickReleaseOnEntity: function(entityId, mouseEvent) { + // print("CLIIICK ON MOUSE") + // if (!mouseEvent.isLeftButton) { + // return; + // } + // }, + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + preload: function(entityID) { + this.entityID = entityID; + var defaultLightData= { + on: false + }; + this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + + //If light is off, then we create two new lights- at the position of the sconces + if (this.lightState.on === false) { + this.createLights(); + } + + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new LightSwitch(); +}) \ No newline at end of file diff --git a/examples/toybox/entityScripts/wand.js b/examples/toybox/entityScripts/wand.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 7fbcc97f4a..ecc657ecc7 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -47,6 +47,8 @@ function createAllToys() { }); createDice(); + + createLightSwitch(); } function deleteAllToys() { @@ -61,32 +63,84 @@ function deleteAllToys() { }) } +function createLightSwitch() { + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.obj"; + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); + var lightSwitch = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Hall", + collisionsWillMove: true, + script: scriptURL, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } + }); + + setEntityCustomData(resetKey, lightSwitch, { + resetMe: true + }); +} + function createDice() { var diceProps = { type: "Model", modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541.1, y: 496, z: 509.21 }, - dimensions: {x: 0.09, y: 0.09, z: 0.09}, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: {x: 0, y: -.01, z: 0}, + position: { + x: 541.1, + y: 496, + z: 509.21 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + }, shapeType: "box", collisionsWillMove: true } var dice1 = Entities.addEntity(diceProps); - diceProps.position = {x: 540.99, y: 496, z: 509.08}; + diceProps.position = { + x: 540.99, + y: 496, + z: 509.08 + }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, { + setEntityCustomData(resetKey, dice1, { resetMe: true }); - setEntityCustomData(resetKey, dice2, { + setEntityCustomData(resetKey, dice2, { resetMe: true - }); + }); } function createWand(position) { @@ -248,26 +302,41 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var blockTypes = [ - { + var blockTypes = [{ url: "planky_blue.fbx", - dimensions: {x: 0.05, y: 0.05, z: 0.25} - }, - { + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { url: "planky_green.fbx", - dimensions: {x: 0.1, y: 0.1, z: 0.25} - }, - { + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { url: "planky_natural.fbx", - dimensions: {x: 0.05, y: 0.05, z: 0.05} - }, - { + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { url: "planky_yellow.fbx", - dimensions: {x: 0.03, y: 0.05, z: 0.25} - }, - { + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { url: "planky_red.fbx", - dimensions: {x: 0.1, y: 0.05, z: 0.25} + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } }, @@ -275,13 +344,13 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; for (var i = 0; i < blockTypes.length; i++) { - for(j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { var modelURL = baseURL + blockTypes[i].url; var entity = Entities.addEntity({ type: "Model", modelURL: modelURL, position: Vec3.sum(position, { - x: j/10, + x: j / 10, y: i / 10, z: 0 }), From e4d630b1fc6b3899d6862f3e26ed6a1dca792f67 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 15:57:03 -0700 Subject: [PATCH 039/418] more light toggling additions --- examples/toybox/entityScripts/lightSwitch.js | 12 ++++++++++-- examples/toybox/masterResetEntity.js | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index bb80d76f57..17709764d6 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -31,7 +31,14 @@ startNearGrab: function() { print("TOGGLE LIGHT") - + this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (this.lightState.on === true) { + //Delete the all the sconce lights + var entities = Entities.findEntities(MyAvatar.position, 100); + entities.forEach(function(entity){ + var resetData = getEntityCustomData(this.resetKey, entity, {}) + }); + } // var position = Entities.getEntityProperties(this.entityID, "position").position; // Audio.playSound(clickSound, { // position: position, @@ -64,7 +71,8 @@ }); setEntityCustomData(this.resetKey, this.sconceLight1, { - resetMe: true + resetMe: true, + lightType: "sconceLight" }); }, diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index ecc657ecc7..f7e0f3524b 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -56,8 +56,9 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue - var shouldReset = getEntityCustomData(resetKey, entity, false); - if (shouldReset) { + var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + print("should reset " + JSON.stringify(shouldReset)); + if (shouldReset === true) { Entities.deleteEntity(entity); } }) From a4e5f707cc0f78f8c09c7420f0c2cc22659b3bf9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 16:35:30 -0700 Subject: [PATCH 040/418] Toggling lights --- examples/toybox/entityScripts/lightSwitch.js | 61 +++++++++++++------- examples/toybox/masterResetEntity.js | 1 - 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 17709764d6..30f490a303 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -30,25 +30,39 @@ startNearGrab: function() { - print("TOGGLE LIGHT") - this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - if (this.lightState.on === true) { - //Delete the all the sconce lights - var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function(entity){ - var resetData = getEntityCustomData(this.resetKey, entity, {}) - }); + + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (lightState.on === true) { + this.clearLights(); + } else if (lightState.on === false) { + this.createLights(); } - // var position = Entities.getEntityProperties(this.entityID, "position").position; - // Audio.playSound(clickSound, { - // position: position, - // volume: 0.05 - // }); }, + clearLights: function() { + print("CLEAR LIGHTS") + var entities = Entities.findEntities(MyAvatar.position, 100); + var self = this;0 + entities.forEach(function(entity) { + var resetData = getEntityCustomData(self.resetKey, entity, {}) + print("NAME OF THING " + Entities.getEntityProperties(entity).name) + print("RESET DATA " + JSON.stringify(resetData)) + if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { + print("DELETE LIGHT") + Entities.deleteEntity(entity); + } + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: false + }); + }, + createLights: function() { - print("CREATE LIGHTS *******************") this.sconceLight1 = Entities.addEntity({ type: "Light", position: { @@ -72,8 +86,13 @@ setEntityCustomData(this.resetKey, this.sconceLight1, { resetMe: true, - lightType: "sconceLight" + lightType: "Sconce Light" }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: true + }); + }, // clickReleaseOnEntity: function(entityId, mouseEvent) { @@ -85,18 +104,18 @@ // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: - preload: function(entityID) { + preload: function(entityID) { this.entityID = entityID; - var defaultLightData= { + var defaultLightData = { on: false }; - this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); //If light is off, then we create two new lights- at the position of the sconces - if (this.lightState.on === false) { + if (lightState.on === false) { this.createLights(); - } - + } + //If lights are on, do nothing! }, }; diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index f7e0f3524b..5736e0d29f 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -57,7 +57,6 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - print("should reset " + JSON.stringify(shouldReset)); if (shouldReset === true) { Entities.deleteEntity(entity); } From 71b7f9ee38a4d18fdbfe5d5ad9d5e7c5490718e3 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 21 Sep 2015 19:14:24 -0700 Subject: [PATCH 041/418] Apostrophe key resets animation state. --- interface/src/avatar/MyAvatar.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ae483988e3..75da84961b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -149,6 +149,23 @@ void MyAvatar::reset() { eulers.x = 0.0f; eulers.z = 0.0f; setOrientation(glm::quat(eulers)); + + // This should be simpler when we have only graph animations always on. + bool isRig = _rig->getEnableRig(); + bool isGraph = _rig->getEnableAnimGraph(); + qApp->setRawAvatarUpdateThreading(false); + setEnableRigAnimations(true); + _skeletonModel.simulate(0.1f); // non-zero + setEnableRigAnimations(false); + _skeletonModel.simulate(0.1f); + if (isRig) { + setEnableRigAnimations(true); + Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true); + } else if (isGraph) { + setEnableAnimGraph(true); + Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true); + } + qApp->setRawAvatarUpdateThreading(); } void MyAvatar::update(float deltaTime) { From 617f0488834f97674a914b7e25a7d13d99146c95 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 22 Sep 2015 13:40:33 +0200 Subject: [PATCH 042/418] Added JS interface to change audio listening position / orientation in Interface - MyAvatar.audioListenerMode change using: MyAvatar.FROM_HEAD , MyAvatar.FROM_CAMERA , MyAvatar.CUSTOM - MyAvatar.customListenPosition and MyAvatar.customListenOrientation are for manual listening positions --- interface/src/Application.cpp | 2 ++ interface/src/Application.h | 4 +-- interface/src/avatar/MyAvatar.cpp | 35 +++++++++++++++++++++- interface/src/avatar/MyAvatar.h | 34 +++++++++++++++++++++ libraries/shared/src/RegisteredMetaTypes.h | 8 ++--- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ee98ce4c25..84d66fc285 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4024,6 +4024,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri // hook our avatar and avatar hash map object into this script engine scriptEngine->registerGlobalObject("MyAvatar", _myAvatar); + qScriptRegisterMetaType(scriptEngine, maAudioListenModeToScriptValue, maAudioListenModeFromScriptValue); + scriptEngine->registerGlobalObject("AvatarList", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Camera", &_myCamera); diff --git a/interface/src/Application.h b/interface/src/Application.h index 0a591bf500..5ea890fc2d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -142,8 +142,8 @@ public: static Application* getInstance() { return qApp; } // TODO: replace fully by qApp static const glm::vec3& getPositionForPath() { return getInstance()->_myAvatar->getPosition(); } static glm::quat getOrientationForPath() { return getInstance()->_myAvatar->getOrientation(); } - static glm::vec3 getPositionForAudio() { return getInstance()->_myAvatar->getHead()->getPosition(); } - static glm::quat getOrientationForAudio() { return getInstance()->_myAvatar->getHead()->getFinalOrientationInWorldFrame(); } + static glm::vec3 getPositionForAudio() { return getInstance()->_myAvatar->getPositionForAudio(); } + static glm::quat getOrientationForAudio() { return getInstance()->_myAvatar->getOrientationForAudio(); } static void initPlugins(); static void shutdownPlugins(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ae483988e3..21b718e404 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -108,7 +108,8 @@ MyAvatar::MyAvatar(RigPointer rig) : _goToPosition(), _goToOrientation(), _rig(rig), - _prevShouldDrawHead(true) + _prevShouldDrawHead(true), + _audioListenerMode(FROM_HEAD) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -1806,3 +1807,35 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { // avatar facing is determined solely by hmd orientation. return createMatFromQuatAndPos(hmdOrientationYawOnly, bodyPos); } + +glm::vec3 MyAvatar::getPositionForAudio() { + switch (_audioListenerMode) { + case AudioListenerMode::FROM_HEAD: + return getHead()->getPosition(); + case AudioListenerMode::FROM_CAMERA: + return Application::getInstance()->getCamera()->getPosition(); + case AudioListenerMode::CUSTOM: + return _customListenPosition; + } + return vec3(); +} + +glm::quat MyAvatar::getOrientationForAudio() { + switch (_audioListenerMode) { + case AudioListenerMode::FROM_HEAD: + return getHead()->getFinalOrientationInWorldFrame(); + case AudioListenerMode::FROM_CAMERA: + return Application::getInstance()->getCamera()->getOrientation(); + case AudioListenerMode::CUSTOM: + return _customListenOrientation; + } + return quat(); +} + +QScriptValue maAudioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode) { + return audioListenerMode; +} + +void maAudioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) { + audioListenerMode = (AudioListenerMode)object.toUInt16(); +} diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6989ea3969..3dfcde735b 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -26,6 +26,14 @@ enum eyeContactTarget { MOUTH }; +enum AudioListenerMode { + FROM_HEAD = 0, + FROM_CAMERA, + CUSTOM +}; +Q_DECLARE_METATYPE(AudioListenerMode); + + class MyAvatar : public Avatar { Q_OBJECT Q_PROPERTY(bool shouldRenderLocally READ getShouldRenderLocally WRITE setShouldRenderLocally) @@ -33,12 +41,21 @@ class MyAvatar : public Avatar { Q_PROPERTY(float motorTimescale READ getScriptedMotorTimescale WRITE setScriptedMotorTimescale) Q_PROPERTY(QString motorReferenceFrame READ getScriptedMotorFrame WRITE setScriptedMotorFrame) Q_PROPERTY(QString collisionSoundURL READ getCollisionSoundURL WRITE setCollisionSoundURL) + Q_PROPERTY(AudioListenerMode audioListenerMode READ getAudioListenerMode WRITE setAudioListenerMode) + Q_PROPERTY(glm::vec3 customListenPosition READ getCustomListenPosition WRITE setCustomListenPosition) + Q_PROPERTY(glm::quat customListenOrientation READ getCustomListenOrientation WRITE setCustomListenOrientation) + Q_PROPERTY(AudioListenerMode FROM_HEAD READ getAudioListenerModeHead) + Q_PROPERTY(AudioListenerMode FROM_CAMERA READ getAudioListenerModeCamera) + Q_PROPERTY(AudioListenerMode CUSTOM READ getAudioListenerModeCustom) //TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity) public: MyAvatar(RigPointer rig); ~MyAvatar(); + AudioListenerMode getAudioListenerModeHead() const { return FROM_HEAD; } + AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } + AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } void reset(); void update(float deltaTime); @@ -153,6 +170,13 @@ public: void doUpdateBillboard(); void destroyAnimGraph(); + AudioListenerMode getAudioListenerMode() { return _audioListenerMode; } + void setAudioListenerMode(AudioListenerMode audioListenerMode) { _audioListenerMode = audioListenerMode; } + glm::vec3 getCustomListenPosition() { return _customListenPosition; } + void setCustomListenPosition(glm::vec3 customListenPosition) { _customListenPosition = customListenPosition; } + glm::quat getCustomListenOrientation() { return _customListenOrientation; } + void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; } + public slots: void increaseSize(); void decreaseSize(); @@ -200,6 +224,9 @@ public slots: void setEnableDebugDrawAnimPose(bool isEnabled); void setEnableMeshVisible(bool isEnabled); + glm::vec3 getPositionForAudio(); + glm::quat getOrientationForAudio(); + signals: void transformChanged(); void newCollisionSoundURL(const QUrl& url); @@ -325,6 +352,13 @@ private: bool _enableDebugDrawBindPose = false; bool _enableDebugDrawAnimPose = false; AnimSkeleton::ConstPointer _debugDrawSkeleton = nullptr; + + AudioListenerMode _audioListenerMode; + glm::vec3 _customListenPosition; + glm::quat _customListenOrientation; }; +QScriptValue maAudioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); +void maAudioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode); + #endif // hifi_MyAvatar_h diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 31f1da8a40..c419741c3b 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -59,7 +59,7 @@ void qURLFromScriptValue(const QScriptValue& object, QUrl& url); QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector& vector); void qVectorVec3FromScriptValue(const QScriptValue& array, QVector& vector); -QVector qVectorVec3FromScriptValue( const QScriptValue& array); +QVector qVectorVec3FromScriptValue(const QScriptValue& array); QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector& vector); void qVectorFloatFromScriptValue(const QScriptValue& array, QVector& vector); @@ -77,10 +77,10 @@ QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay); enum ContactEventType { - CONTACT_EVENT_TYPE_START, + CONTACT_EVENT_TYPE_START, CONTACT_EVENT_TYPE_CONTINUE, - CONTACT_EVENT_TYPE_END -}; + CONTACT_EVENT_TYPE_END +}; class Collision { public: From 81932fe1d7976216a07a01990b81fcbcfb551f75 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 22 Sep 2015 15:38:53 +0200 Subject: [PATCH 043/418] - added MyAvatar.audioListenerModeChanged signal , for registering changes. - updated the developerMenuItems.js script to include AudioListenerMode menu options under Developer > Audio --- .../utilities/tools/developerMenuItems.js | 49 +++++++++++++++---- interface/src/avatar/MyAvatar.cpp | 7 +++ interface/src/avatar/MyAvatar.h | 3 +- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/examples/utilities/tools/developerMenuItems.js b/examples/utilities/tools/developerMenuItems.js index ace2b032e2..3439d85b3b 100644 --- a/examples/utilities/tools/developerMenuItems.js +++ b/examples/utilities/tools/developerMenuItems.js @@ -13,6 +13,7 @@ var createdRenderMenu = false; var createdGeneratedAudioMenu = false; +var createdAudioListenerModeMenu = false; var createdStereoInputMenuItem = false; var DEVELOPER_MENU = "Developer"; @@ -29,6 +30,15 @@ var AUDIO_SOURCE_INJECT = "Generated Audio"; var AUDIO_SOURCE_MENU = AUDIO_MENU + " > Generated Audio Source"; var AUDIO_SOURCE_PINK_NOISE = "Pink Noise"; var AUDIO_SOURCE_SINE_440 = "Sine 440hz"; +var AUDIO_LISTENER_MODE_MENU = AUDIO_MENU + " > Audio Listener Mode" +var AUDIO_LISTENER_MODE_FROM_HEAD = "Audio from head"; +var AUDIO_LISTENER_MODE_FROM_CAMERA = "Audio from camera"; +var AUDIO_LISTENER_MODE_CUSTOM = "Audio from custom position"; +var AUDIO_LISTENER_OPTIONS = [ + AUDIO_LISTENER_MODE_FROM_HEAD, + AUDIO_LISTENER_MODE_FROM_CAMERA, + AUDIO_LISTENER_MODE_CUSTOM +]; var AUDIO_STEREO_INPUT = "Stereo Input"; @@ -67,7 +77,6 @@ function setupMenus() { Menu.addMenuItem({ menuName: RENDER_MENU, menuItemName: AVATARS_ITEM, isCheckable: true, isChecked: Scene.shouldRenderAvatars }) } - if (!Menu.menuExists(AUDIO_MENU)) { Menu.addMenu(AUDIO_MENU); } @@ -80,6 +89,14 @@ function setupMenus() { Audio.selectPinkNoise(); createdGeneratedAudioMenu = true; } + + if (!Menu.menuExists(AUDIO_LISTENER_MODE_MENU)) { + Menu.addMenu(AUDIO_LISTENER_MODE_MENU); + Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_HEAD, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_HEAD) }); + Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_CAMERA, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_CAMERA) }); + Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_CUSTOM, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.CUSTOM) }); + } + if (!Menu.menuItemExists(AUDIO_MENU, AUDIO_STEREO_INPUT)) { Menu.addMenuItem({ menuName: AUDIO_MENU, menuItemName: AUDIO_STEREO_INPUT, isCheckable: true, isChecked: false }); createdStereoInputMenuItem = true; @@ -99,15 +116,23 @@ Menu.menuItemEvent.connect(function (menuItem) { Scene.shouldRenderAvatars = Menu.isOptionChecked(AVATARS_ITEM); } else if (menuItem == AUDIO_SOURCE_INJECT && !createdGeneratedAudioMenu) { Audio.injectGeneratedNoise(Menu.isOptionChecked(AUDIO_SOURCE_INJECT)); - } else if (menuItem == AUDIO_SOURCE_PINK_NOISE && !createdGeneratedAudioMenu) { - Audio.selectPinkNoise(); - Menu.setIsOptionChecked(AUDIO_SOURCE_SINE_440, false); - } else if (menuItem == AUDIO_SOURCE_SINE_440 && !createdGeneratedAudioMenu) { - Audio.selectSine440(); - Menu.setIsOptionChecked(AUDIO_SOURCE_PINK_NOISE, false); - } else if (menuItem == AUDIO_STEREO_INPUT) { - Audio.setStereoInput(Menu.isOptionChecked(AUDIO_STEREO_INPUT)) - } + } else if (menuItem == AUDIO_SOURCE_PINK_NOISE && !createdGeneratedAudioMenu) { + Audio.selectPinkNoise(); + Menu.setIsOptionChecked(AUDIO_SOURCE_SINE_440, false); + } else if (menuItem == AUDIO_SOURCE_SINE_440 && !createdGeneratedAudioMenu) { + Audio.selectSine440(); + Menu.setIsOptionChecked(AUDIO_SOURCE_PINK_NOISE, false); + } else if (menuItem == AUDIO_STEREO_INPUT) { + Audio.setStereoInput(Menu.isOptionChecked(AUDIO_STEREO_INPUT)) + } else if (AUDIO_LISTENER_OPTIONS.indexOf(menuItem) !== -1) { + MyAvatar.audioListenerMode = AUDIO_LISTENER_OPTIONS.indexOf(menuItem); + } +}); + +MyAvatar.audioListenerModeChanged(function() { + for (var i = 0; i < AUDIO_LISTENER_OPTIONS.length; i++) { + Menu.setIsOptionChecked(AUDIO_LISTENER_OPTIONS[i], (MyAvatar.audioListenerMode === i)); + } }); Scene.shouldRenderAvatarsChanged.connect(function(shouldRenderAvatars) { @@ -134,6 +159,10 @@ function scriptEnding() { Menu.removeMenu(AUDIO_SOURCE_MENU); } + if (createdAudioListenerModeMenu) { + Menu.removeMenu(AUDIO_LISTENER_MODE_MENU); + } + if (createdStereoInputMenuItem) { Menu.removeMenuItem(AUDIO_MENU, AUDIO_STEREO_INPUT); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 21b718e404..2b695f3fe2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1832,6 +1832,13 @@ glm::quat MyAvatar::getOrientationForAudio() { return quat(); } +void MyAvatar::setAudioListenerMode(AudioListenerMode audioListenerMode) { + if (_audioListenerMode != audioListenerMode) { + _audioListenerMode = audioListenerMode; + emit audioListenerModeChanged(); + } +} + QScriptValue maAudioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode) { return audioListenerMode; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3dfcde735b..d916977ad5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -171,7 +171,7 @@ public: void destroyAnimGraph(); AudioListenerMode getAudioListenerMode() { return _audioListenerMode; } - void setAudioListenerMode(AudioListenerMode audioListenerMode) { _audioListenerMode = audioListenerMode; } + void setAudioListenerMode(AudioListenerMode audioListenerMode); glm::vec3 getCustomListenPosition() { return _customListenPosition; } void setCustomListenPosition(glm::vec3 customListenPosition) { _customListenPosition = customListenPosition; } glm::quat getCustomListenOrientation() { return _customListenOrientation; } @@ -228,6 +228,7 @@ public slots: glm::quat getOrientationForAudio(); signals: + void audioListenerModeChanged(); void transformChanged(); void newCollisionSoundURL(const QUrl& url); void collisionWithEntity(const Collision& collision); From dfb9034b4e18f9b4b22b9a201c6c8749bb1a4f5c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 22 Sep 2015 15:45:57 +0200 Subject: [PATCH 044/418] - delete new AudioListenerMode menu on script ending - style fix (function naming) --- examples/utilities/tools/developerMenuItems.js | 1 + interface/src/Application.cpp | 2 +- interface/src/avatar/MyAvatar.cpp | 4 ++-- interface/src/avatar/MyAvatar.h | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/utilities/tools/developerMenuItems.js b/examples/utilities/tools/developerMenuItems.js index 3439d85b3b..3fe3a10be7 100644 --- a/examples/utilities/tools/developerMenuItems.js +++ b/examples/utilities/tools/developerMenuItems.js @@ -95,6 +95,7 @@ function setupMenus() { Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_HEAD, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_HEAD) }); Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_CAMERA, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_CAMERA) }); Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_CUSTOM, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.CUSTOM) }); + createdAudioListenerModeMenu = true; } if (!Menu.menuItemExists(AUDIO_MENU, AUDIO_STEREO_INPUT)) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 84d66fc285..32198c5524 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4024,7 +4024,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri // hook our avatar and avatar hash map object into this script engine scriptEngine->registerGlobalObject("MyAvatar", _myAvatar); - qScriptRegisterMetaType(scriptEngine, maAudioListenModeToScriptValue, maAudioListenModeFromScriptValue); + qScriptRegisterMetaType(scriptEngine, audioListenModeToScriptValue, audioListenModeFromScriptValue); scriptEngine->registerGlobalObject("AvatarList", DependencyManager::get().data()); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2b695f3fe2..a80cb456ef 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1839,10 +1839,10 @@ void MyAvatar::setAudioListenerMode(AudioListenerMode audioListenerMode) { } } -QScriptValue maAudioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode) { +QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode) { return audioListenerMode; } -void maAudioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) { +void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) { audioListenerMode = (AudioListenerMode)object.toUInt16(); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d916977ad5..3452a68c47 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -359,7 +359,7 @@ private: glm::quat _customListenOrientation; }; -QScriptValue maAudioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); -void maAudioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode); +QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); +void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode); #endif // hifi_MyAvatar_h From 4d26eb5258e5988d1ebf859c3a67ec137a6a0aad Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 22 Sep 2015 16:20:58 +0200 Subject: [PATCH 045/418] - added some comments - replaced repetitious code with loop - fixed the audioListenerModeChanged signal (forgot connect call) --- examples/utilities/tools/developerMenuItems.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/utilities/tools/developerMenuItems.js b/examples/utilities/tools/developerMenuItems.js index 3fe3a10be7..ef8be8aaa9 100644 --- a/examples/utilities/tools/developerMenuItems.js +++ b/examples/utilities/tools/developerMenuItems.js @@ -34,9 +34,14 @@ var AUDIO_LISTENER_MODE_MENU = AUDIO_MENU + " > Audio Listener Mode" var AUDIO_LISTENER_MODE_FROM_HEAD = "Audio from head"; var AUDIO_LISTENER_MODE_FROM_CAMERA = "Audio from camera"; var AUDIO_LISTENER_MODE_CUSTOM = "Audio from custom position"; + +// be sure that the audio listener options are in the right order (same as the enumerator) var AUDIO_LISTENER_OPTIONS = [ + // MyAvatar.FROM_HEAD (0) AUDIO_LISTENER_MODE_FROM_HEAD, + // MyAvatar.FROM_CAMERA (1) AUDIO_LISTENER_MODE_FROM_CAMERA, + // MyAvatar.CUSTOM (2) AUDIO_LISTENER_MODE_CUSTOM ]; var AUDIO_STEREO_INPUT = "Stereo Input"; @@ -92,9 +97,9 @@ function setupMenus() { if (!Menu.menuExists(AUDIO_LISTENER_MODE_MENU)) { Menu.addMenu(AUDIO_LISTENER_MODE_MENU); - Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_HEAD, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_HEAD) }); - Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_FROM_CAMERA, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.FROM_CAMERA) }); - Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_MODE_CUSTOM, isCheckable: true, isChecked: (MyAvatar.audioListenerMode === MyAvatar.CUSTOM) }); + for (var i = 0; i < AUDIO_LISTENER_OPTIONS.length; i++) { + Menu.addMenuItem({ menuName: AUDIO_LISTENER_MODE_MENU, menuItemName: AUDIO_LISTENER_OPTIONS[i], isCheckable: true, isChecked: (MyAvatar.audioListenerMode === i) }); + } createdAudioListenerModeMenu = true; } @@ -130,10 +135,10 @@ Menu.menuItemEvent.connect(function (menuItem) { } }); -MyAvatar.audioListenerModeChanged(function() { +MyAvatar.audioListenerModeChanged.connect(function() { for (var i = 0; i < AUDIO_LISTENER_OPTIONS.length; i++) { Menu.setIsOptionChecked(AUDIO_LISTENER_OPTIONS[i], (MyAvatar.audioListenerMode === i)); - } + } }); Scene.shouldRenderAvatarsChanged.connect(function(shouldRenderAvatars) { From 68bee8228b5f25bbd3d3220eb503a7efa856dad1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 08:53:46 -0700 Subject: [PATCH 046/418] abstracted toggle logic to work with mouse click as well --- examples/toybox/entityScripts/lightSwitch.js | 56 ++++++++++++++------ examples/toybox/masterResetEntity.js | 3 ++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 30f490a303..99d98d943f 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -30,7 +30,18 @@ startNearGrab: function() { + this.toggleLights(); + }, + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.toggleLights(); + }, + + toggleLights: function() { var defaultLightData = { on: false }; @@ -44,15 +55,11 @@ }, clearLights: function() { - print("CLEAR LIGHTS") var entities = Entities.findEntities(MyAvatar.position, 100); - var self = this;0 + var self = this; entities.forEach(function(entity) { var resetData = getEntityCustomData(self.resetKey, entity, {}) - print("NAME OF THING " + Entities.getEntityProperties(entity).name) - print("RESET DATA " + JSON.stringify(resetData)) if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { - print("DELETE LIGHT") Entities.deleteEntity(entity); } }); @@ -63,7 +70,7 @@ }, createLights: function() { - this.sconceLight1 = Entities.addEntity({ + var sconceLight1 = Entities.addEntity({ type: "Light", position: { x: 543.62, @@ -84,7 +91,33 @@ } }); - setEntityCustomData(this.resetKey, this.sconceLight1, { + setEntityCustomData(this.resetKey, sconceLight1, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 539.87, + y: 496.24, + z: 505.77 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight2, { resetMe: true, lightType: "Sconce Light" }); @@ -95,13 +128,6 @@ }, - // clickReleaseOnEntity: function(entityId, mouseEvent) { - // print("CLIIICK ON MOUSE") - // if (!mouseEvent.isLeftButton) { - // return; - // } - // }, - // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { @@ -114,7 +140,7 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); - } + } //If lights are on, do nothing! }, }; diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 5736e0d29f..1fe1f570d9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,6 +48,7 @@ function createAllToys() { createDice(); + //Handles toggling of all sconce lights createLightSwitch(); } @@ -57,6 +58,8 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + print("ENTITY " + Entities.getEntityProperties(entity).name) + print("SHOULD RESET " + JSON.stringify(shouldReset)) if (shouldReset === true) { Entities.deleteEntity(entity); } From 703545bac311904e82d4fd5204a7ba60e1e0f322 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:34:54 -0700 Subject: [PATCH 047/418] Modified lightSwitch entity to use new incoming grab API --- examples/toybox/entityScripts/lightSwitch.js | 10 ++++------ examples/toybox/masterResetEntity.js | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 99d98d943f..2420011951 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -28,12 +28,6 @@ LightSwitch.prototype = { - - startNearGrab: function() { - this.toggleLights(); - - }, - clickReleaseOnEntity: function(entityId, mouseEvent) { if (!mouseEvent.isLeftButton) { return; @@ -41,6 +35,10 @@ this.toggleLights(); }, + startNearTouch: function(){ + this.toggleLights(); + }, + toggleLights: function() { var defaultLightData = { on: false diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 1fe1f570d9..80a45ef9bc 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -58,8 +58,6 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - print("ENTITY " + Entities.getEntityProperties(entity).name) - print("SHOULD RESET " + JSON.stringify(shouldReset)) if (shouldReset === true) { Entities.deleteEntity(entity); } @@ -73,7 +71,6 @@ function createLightSwitch() { type: "Model", modelURL: modelURL, name: "Light Switch Hall", - collisionsWillMove: true, script: scriptURL, position: { x: 543.27764892578125, From b9db495ebf78e85ada8f1b5faf1fa954fe6ecfbb Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:38:06 -0700 Subject: [PATCH 048/418] Modified handControllerGrab script to trigger entity touch events for non-physical entities --- examples/controllers/handControllerGrab.js | 100 +++++++++++++++------ 1 file changed, 74 insertions(+), 26 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index f57e79e974..0fa32baf53 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,9 +29,21 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = {red: 10, green: 10, blue: 255}; // line color when pick misses -var INTERSECT_COLOR = {red: 250, green: 10, blue: 10}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = {x: 1000, y: 1000, z: 1000}; +var NO_INTERSECT_COLOR = { + red: 10, + green: 10, + blue: 255 +}; // line color when pick misses +var INTERSECT_COLOR = { + red: 250, + green: 10, + blue: 10 +}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { + x: 1000, + y: 1000, + z: 1000 +}; var LINE_LENGTH = 500; @@ -54,7 +66,11 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var RIGHT_HAND = 1; var LEFT_HAND = 0; -var ZERO_VEC = {x: 0, y: 0, z: 0}; +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +}; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; @@ -68,7 +84,9 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_RELEASE = 5; +var STATE_NEAR_TOUCHING = 5; +var STATE_CONTINUE_NEAR_TOUCHING = 6; +var STATE_RELEASE = 7; var GRAB_USER_DATA_KEY = "grabKey"; @@ -93,7 +111,7 @@ function controller(hand, triggerAction) { this.triggerValue = 0; // rolling average of trigger value this.update = function() { - switch(this.state) { + switch (this.state) { case STATE_SEARCHING: this.search(); break; @@ -109,6 +127,12 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; + case STATE_NEAR_TOUCHING: + this.nearTouching(); + break; + case STATE_CONTINUE_NEAR_TOUCHING: + this.continueNearTouching(); + break; case STATE_RELEASE: this.release(); break; @@ -125,14 +149,14 @@ function controller(hand, triggerAction) { dimensions: LINE_ENTITY_DIMENSIONS, visible: true, position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: LIFETIME }); } else { Entities.editEntity(this.pointer, { position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME }); @@ -171,7 +195,10 @@ function controller(hand, triggerAction) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); - var pickRay = {origin: handPosition, direction: Quat.getUp(this.getHandRotation())}; + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && @@ -189,24 +216,25 @@ function controller(hand, triggerAction) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); } } else { - // forward ray test failed, try sphere test. + // forward ray test failed, try sphere test. var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { var props = Entities.getEntityProperties(nearbyEntities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer" && - props.collisionsWillMove === 1 && - props.locked === 0) { + if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; } } if (this.grabbedEntity === null) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else { + } else if (props.locked === 0 && props.collisionsWillMove === 1) { this.state = STATE_NEAR_GRABBING; + } else if (props.collisionsWillMove === 0) { + // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event + this.state = STATE_NEAR_TOUCHING; } } } @@ -215,7 +243,7 @@ function controller(hand, triggerAction) { this.distanceHolding = function() { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]); + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); // add the action and initialize some variables this.currentObjectPosition = grabbedProperties.position; @@ -263,8 +291,8 @@ function controller(hand, triggerAction) { // the action was set up on a previous call. update the targets. var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); + handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, + DISTANCE_HOLDING_RADIUS_FACTOR); var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; @@ -281,16 +309,18 @@ function controller(hand, triggerAction) { // this doubles hand rotation var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); + DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), + Quat.inverse(this.handPreviousRotation)); this.handPreviousRotation = handRotation; this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab"); Entities.updateAction(this.grabbedEntity, this.actionID, { - targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME }); } @@ -339,6 +369,23 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } + this.nearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") + this.state = STATE_CONTINUE_NEAR_TOUCHING; + } + + this.continueNearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); + } + this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { @@ -367,9 +414,8 @@ function controller(hand, triggerAction) { // value would otherwise give the held object time to slow down. if (this.triggerSqueezed()) { this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, - (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); + Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), + Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); } if (useMultiplier) { @@ -389,7 +435,9 @@ function controller(hand, triggerAction) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, {velocity: this.grabbedVelocity}); + Entities.editEntity(this.grabbedEntity, { + velocity: this.grabbedVelocity + }); this.deactivateEntity(this.grabbedEntity); this.grabbedVelocity = ZERO_VEC; @@ -438,4 +486,4 @@ function cleanup() { Script.scriptEnding.connect(cleanup); -Script.update.connect(update) +Script.update.connect(update) \ No newline at end of file From 98faf3d712bec241f1da347c83107fbfcd4c1505 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:53:22 -0700 Subject: [PATCH 049/418] Added light switch sound --- examples/controllers/handControllerGrab.js | 98 +++++++++++++++----- examples/toybox/entityScripts/lightSwitch.js | 10 ++ 2 files changed, 83 insertions(+), 25 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index f57e79e974..40e3879220 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,9 +29,21 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = {red: 10, green: 10, blue: 255}; // line color when pick misses -var INTERSECT_COLOR = {red: 250, green: 10, blue: 10}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = {x: 1000, y: 1000, z: 1000}; +var NO_INTERSECT_COLOR = { + red: 10, + green: 10, + blue: 255 +}; // line color when pick misses +var INTERSECT_COLOR = { + red: 250, + green: 10, + blue: 10 +}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { + x: 1000, + y: 1000, + z: 1000 +}; var LINE_LENGTH = 500; @@ -54,7 +66,11 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var RIGHT_HAND = 1; var LEFT_HAND = 0; -var ZERO_VEC = {x: 0, y: 0, z: 0}; +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +}; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; @@ -68,7 +84,9 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_RELEASE = 5; +var STATE_NEAR_TOUCHING = 5; +var STATE_CONTINUE_NEAR_TOUCHING = 6; +var STATE_RELEASE = 7; var GRAB_USER_DATA_KEY = "grabKey"; @@ -93,7 +111,7 @@ function controller(hand, triggerAction) { this.triggerValue = 0; // rolling average of trigger value this.update = function() { - switch(this.state) { + switch (this.state) { case STATE_SEARCHING: this.search(); break; @@ -109,6 +127,12 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; + case STATE_NEAR_TOUCHING: + this.nearTouching(); + break; + case STATE_CONTINUE_NEAR_TOUCHING: + this.continueNearTouching(); + break; case STATE_RELEASE: this.release(); break; @@ -125,14 +149,14 @@ function controller(hand, triggerAction) { dimensions: LINE_ENTITY_DIMENSIONS, visible: true, position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: LIFETIME }); } else { Entities.editEntity(this.pointer, { position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME }); @@ -171,7 +195,10 @@ function controller(hand, triggerAction) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); - var pickRay = {origin: handPosition, direction: Quat.getUp(this.getHandRotation())}; + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && @@ -196,17 +223,18 @@ function controller(hand, triggerAction) { for (var i = 0; i < nearbyEntities.length; i++) { var props = Entities.getEntityProperties(nearbyEntities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer" && - props.collisionsWillMove === 1 && - props.locked === 0) { + if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; } } if (this.grabbedEntity === null) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else { + } else if (props.locked === 0 && props.collisionsWillMove === 1) { this.state = STATE_NEAR_GRABBING; + } else if (props.collisionsWillMove === 0) { + // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event + this.state = STATE_NEAR_TOUCHING; } } } @@ -215,7 +243,7 @@ function controller(hand, triggerAction) { this.distanceHolding = function() { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]); + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); // add the action and initialize some variables this.currentObjectPosition = grabbedProperties.position; @@ -263,8 +291,8 @@ function controller(hand, triggerAction) { // the action was set up on a previous call. update the targets. var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); + handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, + DISTANCE_HOLDING_RADIUS_FACTOR); var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; @@ -281,16 +309,18 @@ function controller(hand, triggerAction) { // this doubles hand rotation var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); + DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), + Quat.inverse(this.handPreviousRotation)); this.handPreviousRotation = handRotation; this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab"); Entities.updateAction(this.grabbedEntity, this.actionID, { - targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME }); } @@ -339,6 +369,23 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } + this.nearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") + this.state = STATE_CONTINUE_NEAR_TOUCHING; + } + + this.continueNearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); + } + this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { @@ -367,9 +414,8 @@ function controller(hand, triggerAction) { // value would otherwise give the held object time to slow down. if (this.triggerSqueezed()) { this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, - (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); + Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), + Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); } if (useMultiplier) { @@ -389,7 +435,9 @@ function controller(hand, triggerAction) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, {velocity: this.grabbedVelocity}); + Entities.editEntity(this.grabbedEntity, { + velocity: this.grabbedVelocity + }); this.deactivateEntity(this.grabbedEntity); this.grabbedVelocity = ZERO_VEC; @@ -438,4 +486,4 @@ function cleanup() { Script.scriptEnding.connect(cleanup); -Script.update.connect(update) +Script.update.connect(update) \ No newline at end of file diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 2420011951..5bf2b5a04d 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -24,6 +24,8 @@ this.lightStateKey = "lightStateKey"; this.resetKey = "resetMe"; + this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); + }; LightSwitch.prototype = { @@ -50,6 +52,11 @@ this.createLights(); } + Audio.playSound(this.switchSound, { + volume: 1, + position: this.position + }); + }, clearLights: function() { @@ -130,6 +137,9 @@ // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { this.entityID = entityID; + + //The light switch is static, so just cache its position once + this.position = Entities.getEntityProperties(this.entityID, "position").position; var defaultLightData = { on: false }; From b704ebd9348a55b372b309368fe60d2d803be360 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:55:24 -0700 Subject: [PATCH 050/418] modified dice starting position --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 80a45ef9bc..be035d4252 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -102,7 +102,7 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 541.1, + x: 540.74, y: 496, z: 509.21 }, From 2557b32e1a70cc78724c0e478e938ff27ea9fba4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:40:09 -0700 Subject: [PATCH 051/418] Updated switch model to be fbx --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index be035d4252..8cc25dc3bf 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -65,7 +65,7 @@ function deleteAllToys() { } function createLightSwitch() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.obj"; + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); var lightSwitch = Entities.addEntity({ type: "Model", From a266e8d65a47d994515520c9f8b58d95db7aab28 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:49:45 -0700 Subject: [PATCH 052/418] updated reset script to use new wand script --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 8cc25dc3bf..4b0a2f986a 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -147,7 +147,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/ccf125c047426a2c481d3ee8c58a05fc6048fdde/examples/toys/bubblewand/wand.js" + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/f8d743aff0700f81d7f2ace92b8718e1e5e64978/examples/toys/bubblewand/wand.js" var entity = Entities.addEntity({ name: 'Bubble Wand', From d273852bf9af6d063c30150b317d1fd8539d1ea7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:56:01 -0700 Subject: [PATCH 053/418] New wand script --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 4b0a2f986a..27b07968a9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -147,7 +147,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/f8d743aff0700f81d7f2ace92b8718e1e5e64978/examples/toys/bubblewand/wand.js" + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/bubblewand_hotfix_2/examples/toys/bubblewand/wand.js" var entity = Entities.addEntity({ name: 'Bubble Wand', From 6298dcb2fc9f3b4c374c7192608bdc67bb625c12 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:03:44 -0700 Subject: [PATCH 054/418] attempt fix for doll animation --- examples/toybox/entityScripts/doll.js | 2 +- examples/toybox/masterResetEntity.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 86e7fcc62c..ed4f7983ba 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -53,7 +53,7 @@ releaseGrab: function() { Entities.editEntity(this.entityID, { animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - // animationSettings: this.stopAnimationSetting + animationSettings: this.stopAnimationSetting }); }, diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 27b07968a9..f397616487 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,6 +48,8 @@ function createAllToys() { createDice(); + createFlashlight(); + //Handles toggling of all sconce lights createLightSwitch(); } From a0bf7b65297ee65dc2dc529180f5478ec999b554 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:20:17 -0700 Subject: [PATCH 055/418] doll animation fixes --- examples/toybox/entityScripts/doll.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index ed4f7983ba..63a3d91ef6 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -29,7 +29,7 @@ }); this.stopAnimationSetting = JSON.stringify({ - running: false + running: false, }); }; @@ -37,6 +37,7 @@ startNearGrab: function() { + print("START GRAB") Entities.editEntity(this.entityID, { animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting @@ -53,7 +54,8 @@ releaseGrab: function() { Entities.editEntity(this.entityID, { animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - animationSettings: this.stopAnimationSetting + // animationSettings: this.stopAnimationSetting, + // animationFrameIndex: 0 }); }, From a28cf5ce8bdb5b0eb397e65090d03fa0e55b2d61 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:29:16 -0700 Subject: [PATCH 056/418] updated grab script --- examples/controllers/handControllerGrab.js | 2 +- examples/toybox/entityScripts/doll.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 40e3879220..af1c97da68 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -221,7 +221,7 @@ function controller(hand, triggerAction) { var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i]); + var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); var distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 63a3d91ef6..a9c2d4e830 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -37,7 +37,6 @@ startNearGrab: function() { - print("START GRAB") Entities.editEntity(this.entityID, { animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting From 42a2125336a7edfba03b9e662f1e175ef85fd7ff Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:29:54 -0700 Subject: [PATCH 057/418] Only asking for needed props --- examples/controllers/handControllerGrab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0fa32baf53..af1c97da68 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -216,12 +216,12 @@ function controller(hand, triggerAction) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); } } else { - // forward ray test failed, try sphere test. + // forward ray test failed, try sphere test. var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i]); + var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); var distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; From 5546a04f4d83d4fda5fc2c6d2d5ac9bfc934470e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:48:10 -0700 Subject: [PATCH 058/418] Added flashlight to master script --- examples/toybox/masterResetEntity.js | 55 ++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index f397616487..85df03e3b4 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,10 +48,18 @@ function createAllToys() { createDice(); - createFlashlight(); + createFlashlight({ + x: 546, + y: 495.65, + z: 506.1 + }); //Handles toggling of all sconce lights - createLightSwitch(); + createLightSwitch({ + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }); } function deleteAllToys() { @@ -66,7 +74,42 @@ function deleteAllToys() { }) } -function createLightSwitch() { +function createFlashlight(position) { + var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); + var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; + + var flashlight = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "flashlight", + script: scriptURL, + position: position, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + }, + shapeType: 'box', + }); + + setEntityCustomData(resetKey, flashlight, { + resetMe: true + }); + +} + +function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); var lightSwitch = Entities.addEntity({ @@ -74,11 +117,7 @@ function createLightSwitch() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, + position: position, rotation: { w: 0.63280689716339111, x: 0.63280689716339111, From 1e09c2501c9b33f5311be4c7402df89481af4edf Mon Sep 17 00:00:00 2001 From: James Pollack Date: Tue, 22 Sep 2015 14:21:14 -0700 Subject: [PATCH 059/418] This updates the flashlight to have sounds when it turns on and off --- examples/toys/flashlight/flashlight.js | 50 ++++++++++++++------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/examples/toys/flashlight/flashlight.js b/examples/toys/flashlight/flashlight.js index 0465266b1c..5afaed829c 100644 --- a/examples/toys/flashlight/flashlight.js +++ b/examples/toys/flashlight/flashlight.js @@ -18,6 +18,8 @@ (function() { Script.include("../../libraries/utils.js"); + var ON_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; + var OFF_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_off.wav'; var _this; @@ -78,7 +80,7 @@ this.hand = 'LEFT'; }, startNearGrab: function() { - if (!_this.hasSpotlight) { + if (!this.hasSpotlight) { //this light casts the beam this.spotlight = Entities.addEntity({ @@ -117,21 +119,7 @@ cutoff: 90, // in degrees }); - this.debugBox = Entities.addEntity({ - type: 'Box', - color: { - red: 255, - blue: 0, - green: 0 - }, - dimensions: { - x: 0.25, - y: 0.25, - z: 0.25 - }, - ignoreForCollisions:true - }) - + this.hasSpotlight = true; } @@ -158,7 +146,7 @@ this.glowLight = null; this.spotlight = null; this.whichHand = null; - + this.lightOn = false; } }, updateLightPositions: function() { @@ -181,11 +169,6 @@ rotation: glowLightTransform.q, }) - // Entities.editEntity(this.debugBox, { - // position: lightTransform.p, - // rotation: lightTransform.q, - // }) - }, changeLightWithTriggerPressure: function(flashLightHand) { @@ -203,6 +186,7 @@ return }, turnLightOff: function() { + this.playSoundAtCurrentPosition(false); Entities.editEntity(this.spotlight, { intensity: 0 }); @@ -210,8 +194,12 @@ intensity: 0 }); this.lightOn = false + + }, turnLightOn: function() { + this.playSoundAtCurrentPosition(true); + Entities.editEntity(this.glowLight, { intensity: 2 }); @@ -225,6 +213,23 @@ // * remembering our entityID, so we can access it in cases where we're called without an entityID preload: function(entityID) { this.entityID = entityID; + this.ON_SOUND = SoundCache.getSound(ON_SOUND_URL); + this.OFF_SOUND = SoundCache.getSound(OFF_SOUND_URL); + + }, + playSoundAtCurrentPosition: function(playOnSound) { + var position = Entities.getEntityProperties(this.entityID, "position").position; + + var audioProperties = { + volume: 0.5, + position: position + } + if (playOnSound) { + Audio.playSound(this.ON_SOUND, audioProperties) + } else { + Audio.playSound(this.OFF_SOUND, audioProperties) + + } }, // unload() will be called when our entity is no longer available. It may be because we were deleted, @@ -238,6 +243,7 @@ this.glowLight = null; this.spotlight = null; this.whichHand = null; + this.lightOn = false; } From 55f76a4296df0a17dd0a9f83384c561f885cb58b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:45:18 -0700 Subject: [PATCH 060/418] Added more sconce lights to lightSwitch.js --- examples/toybox/entityScripts/lightSwitch.js | 86 +++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 5bf2b5a04d..089e532400 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function(){ + startNearTouch: function() { this.toggleLights(); }, @@ -54,7 +54,7 @@ Audio.playSound(this.switchSound, { volume: 1, - position: this.position + position: this.position }); }, @@ -127,6 +127,88 @@ lightType: "Sconce Light" }); + var sconceLight3 = Entities.addEntity({ + type: "Light", + position: { + x: 545.49468994140625, + y: 496.24026489257812, + z: 500.63516235351562 + }, + + name: "Sconce 3 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight3, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight4 = Entities.addEntity({ + type: "Light", + position: { + x: 550.90399169921875, + y: 496.24026489257812, + z: 507.90237426757812 + }, + + name: "Sconce 4 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight4, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight5 = Entities.addEntity({ + type: "Light", + position: { + x: 548.407958984375, + y: 496.24026489257812, + z: 509.5504150390625 + }, + name: "Sconce 5 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight5, { + resetMe: true, + lightType: "Sconce Light" + }); + + + setEntityCustomData(this.lightStateKey, this.entityID, { on: true }); From ad0c0d3b2bb8210571475dacd317e164008d8f4f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:50:06 -0700 Subject: [PATCH 061/418] no v1 to avoid caching --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 85df03e3b4..06deafce98 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -111,7 +111,7 @@ function createFlashlight(position) { function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js"); var lightSwitch = Entities.addEntity({ type: "Model", modelURL: modelURL, From f2afd666156f7ac1ad6068a40521d2cd5433d907 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:50:46 -0700 Subject: [PATCH 062/418] v2? --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 06deafce98..ed1d3727f1 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -111,7 +111,7 @@ function createFlashlight(position) { function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js"); + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v2"); var lightSwitch = Entities.addEntity({ type: "Model", modelURL: modelURL, From 99dc5a51273ec78c49c7c35e5a61c4d1f0b6f58c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:55:35 -0700 Subject: [PATCH 063/418] updated doll's sound when picked up --- examples/toybox/entityScripts/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index a9c2d4e830..673d143d02 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -21,7 +21,7 @@ Doll = function() { _this = this; var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; + this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; this.startAnimationSetting = JSON.stringify({ running: true, startFrame: 0, @@ -45,7 +45,7 @@ var position = Entities.getEntityProperties(this.entityID, "position").position; Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { position: position, - volume: 0.01 + volume: 0.1 }); }, From deaa4a747b57d1996365df5a5d45a1bcfa70942d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 22 Sep 2015 10:11:49 -0700 Subject: [PATCH 064/418] Batch side implementation of multi-draw indirect --- libraries/gpu/src/gpu/Batch.cpp | 27 +++ libraries/gpu/src/gpu/Batch.h | 36 +++- libraries/gpu/src/gpu/GLBackend.cpp | 56 +++++- libraries/gpu/src/gpu/GLBackend.h | 13 +- libraries/gpu/src/gpu/GLBackendInput.cpp | 37 ++-- libraries/render-utils/src/GeometryCache.cpp | 17 +- libraries/render-utils/src/GeometryCache.h | 14 +- tests/gpu-test/src/main.cpp | 196 +++++++++++++++---- 8 files changed, 318 insertions(+), 78 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index e6e176be88..15b841dd04 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -102,6 +102,19 @@ void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, ui _params.push_back(nbInstances); } + +void Batch::multiDrawIndirect(uint32 nbCommands, Primitive primitiveType) { + ADD_COMMAND(multiDrawIndirect); + _params.push_back(nbCommands); + _params.push_back(primitiveType); +} + +void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) { + ADD_COMMAND(multiDrawIndexedIndirect); + _params.push_back(nbCommands); + _params.push_back(primitiveType); +} + void Batch::setInputFormat(const Stream::FormatPointer& format) { ADD_COMMAND(setInputFormat); @@ -144,6 +157,15 @@ void Batch::setIndexBuffer(const BufferView& buffer) { setIndexBuffer(buffer._element.getType(), buffer._buffer, buffer._offset); } +void Batch::setIndirectBuffer(const BufferPointer& buffer, Offset offset, Offset stride) { + ADD_COMMAND(setIndirectBuffer); + + _params.push_back(_buffers.cache(buffer)); + _params.push_back(offset); + _params.push_back(stride); +} + + void Batch::setModelTransform(const Transform& model) { ADD_COMMAND(setModelTransform); @@ -288,6 +310,11 @@ void Batch::resetStages() { ADD_COMMAND(resetStages); } +void Batch::runLambda(std::function f) { + ADD_COMMAND(runLambda); + _params.push_back(_lambdas.cache(f)); +} + void Batch::enableStereo(bool enable) { _enableStereo = enable; } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index ec6fb26c34..6dd92739c5 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -63,8 +63,8 @@ public: void process(Batch& batch) { if (_function) { - _function(batch, *this); - } + _function(batch, *this); + } } }; @@ -96,12 +96,15 @@ public: void drawIndexed(Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0); void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0); void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0); + void multiDrawIndirect(uint32 nbCommands, Primitive primitiveType); + void multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType); void setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function); void setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function); BufferPointer getNamedBuffer(const std::string& instanceName, uint8_t index = 0); - + void setNamedBuffer(const std::string& instanceName, BufferPointer& buffer, uint8_t index = 0); + // Input Stage @@ -117,6 +120,8 @@ public: void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset); void setIndexBuffer(const BufferView& buffer); // not a command, just a shortcut from a BufferView + void setIndirectBuffer(const BufferPointer& buffer, Offset offset = 0, Offset stride = 0); + // Transform Stage // Vertex position is transformed by ModelTransform from object space to world space // Then by the inverse of the ViewTransform from world space to eye space @@ -169,6 +174,8 @@ public: // Reset the stage caches and states void resetStages(); + void runLambda(std::function f); + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -194,10 +201,13 @@ public: COMMAND_drawIndexed, COMMAND_drawInstanced, COMMAND_drawIndexedInstanced, + COMMAND_multiDrawIndirect, + COMMAND_multiDrawIndexedIndirect, COMMAND_setInputFormat, COMMAND_setInputBuffer, COMMAND_setIndexBuffer, + COMMAND_setIndirectBuffer, COMMAND_setModelTransform, COMMAND_setViewTransform, @@ -221,6 +231,8 @@ public: COMMAND_resetStages, + COMMAND_runLambda, + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -302,6 +314,7 @@ public: typedef Cache::Vector PipelineCaches; typedef Cache::Vector FramebufferCaches; typedef Cache::Vector QueryCaches; + typedef Cache>::Vector LambdaCache; // Cache Data in a byte array if too big to fit in Param // FOr example Mat4s are going there @@ -327,6 +340,7 @@ public: PipelineCaches _pipelines; FramebufferCaches _framebuffers; QueryCaches _queries; + LambdaCache _lambdas; NamedBatchDataMap _namedData; @@ -336,6 +350,20 @@ public: protected: }; -}; +template +void popVectorParam(Batch::Params& params, uint32& paramOffset, V& v) { + for (size_t i = 0; i < v.length(); ++i) { + v[i] = params[paramOffset++]._float; + } +} + +template +void pushVectorParam(Batch::Params& params, const V& v) { + for (size_t i = 0; i < v.length(); ++i) { + params.push_back(v[i]); + } +} + +} #endif diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 62508f273c..79b37ddc0e 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -23,10 +23,13 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_drawIndexed), (&::gpu::GLBackend::do_drawInstanced), (&::gpu::GLBackend::do_drawIndexedInstanced), - + (&::gpu::GLBackend::do_multiDrawIndirect), + (&::gpu::GLBackend::do_multiDrawIndexedIndirect), + (&::gpu::GLBackend::do_setInputFormat), (&::gpu::GLBackend::do_setInputBuffer), (&::gpu::GLBackend::do_setIndexBuffer), + (&::gpu::GLBackend::do_setIndirectBuffer), (&::gpu::GLBackend::do_setModelTransform), (&::gpu::GLBackend::do_setViewTransform), @@ -50,6 +53,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_resetStages), + (&::gpu::GLBackend::do_runLambda), + (&::gpu::GLBackend::do_glActiveBindTexture), (&::gpu::GLBackend::do_glUniform1i), @@ -323,6 +328,9 @@ void GLBackend::do_drawInstanced(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +// DO NOT MERGE THIS, it will break mac clients +#define GL_430 + void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { updateInput(); updateTransform(); @@ -332,17 +340,63 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 3]._uint]; uint32 numIndices = batch._params[paramOffset + 2]._uint; uint32 startIndex = batch._params[paramOffset + 1]._uint; + // FIXME glDrawElementsInstancedBaseVertexBaseInstance is only available in GL 4.3 + // and higher, so currently we ignore this field uint32 startInstance = batch._params[paramOffset + 0]._uint; GLenum glType = _elementTypeToGLType[_input._indexBufferType]; +#ifdef GL_430 + glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, reinterpret_cast(startIndex + _input._indexBufferOffset), numInstances, 0, startInstance); +#else glDrawElementsInstanced(mode, numIndices, glType, reinterpret_cast(startIndex + _input._indexBufferOffset), numInstances); +#endif (void)CHECK_GL_ERROR(); } + +void GLBackend::do_multiDrawIndirect(Batch& batch, uint32 paramOffset) { +#ifdef GL_430 + updateInput(); + updateTransform(); + updatePipeline(); + + uint commandCount = batch._params[paramOffset + 0]._uint; + GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint]; + + glMultiDrawArraysIndirect(mode, reinterpret_cast(_input._indirectBufferOffset), commandCount, _input._indirectBufferStride); +#else + // FIXME implement the slow path +#endif + (void)CHECK_GL_ERROR(); +} + +void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, uint32 paramOffset) { +#ifdef GL_430 + updateInput(); + updateTransform(); + updatePipeline(); + + uint commandCount = batch._params[paramOffset + 0]._uint; + GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint]; + GLenum indexType = _elementTypeToGLType[_input._indexBufferType]; + + glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast(_input._indirectBufferOffset), commandCount, _input._indirectBufferStride); +#else + // FIXME implement the slow path +#endif + (void)CHECK_GL_ERROR(); +} + + void GLBackend::do_resetStages(Batch& batch, uint32 paramOffset) { resetStages(); } +void GLBackend::do_runLambda(Batch& batch, uint32 paramOffset) { + std::function f = batch._lambdas.get(batch._params[paramOffset]._uint); + f(); +} + void GLBackend::resetStages() { resetInputStage(); resetPipelineStage(); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index dabc69dedb..f12cda827a 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -252,11 +252,14 @@ protected: void do_drawIndexed(Batch& batch, uint32 paramOffset); void do_drawInstanced(Batch& batch, uint32 paramOffset); void do_drawIndexedInstanced(Batch& batch, uint32 paramOffset); - + void do_multiDrawIndirect(Batch& batch, uint32 paramOffset); + void do_multiDrawIndexedIndirect(Batch& batch, uint32 paramOffset); + // Input Stage void do_setInputFormat(Batch& batch, uint32 paramOffset); void do_setInputBuffer(Batch& batch, uint32 paramOffset); void do_setIndexBuffer(Batch& batch, uint32 paramOffset); + void do_setIndirectBuffer(Batch& batch, uint32 paramOffset); void initInput(); void killInput(); @@ -284,6 +287,10 @@ protected: Offset _indexBufferOffset; Type _indexBufferType; + BufferPointer _indirectBuffer; + Offset _indirectBufferOffset{ 0 }; + Offset _indirectBufferStride{ 0 }; + GLuint _defaultVAO; InputStageState() : @@ -448,6 +455,9 @@ protected: // Reset stages void do_resetStages(Batch& batch, uint32 paramOffset); + + void do_runLambda(Batch& batch, uint32 paramOffset); + void resetStages(); // TODO: As long as we have gl calls explicitely issued from interface @@ -471,7 +481,6 @@ protected: static CommandCall _commandCalls[Batch::NUM_COMMANDS]; }; - }; #endif diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 7f021fd5c5..2b14e4d7f0 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -273,21 +273,36 @@ void GLBackend::resetInputStage() { } void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) { - _input._indexBufferType = (Type) batch._params[paramOffset + 2]._uint; - BufferPointer indexBuffer = batch._buffers.get(batch._params[paramOffset + 1]._uint); + _input._indexBufferType = (Type)batch._params[paramOffset + 2]._uint; _input._indexBufferOffset = batch._params[paramOffset + 0]._uint; - _input._indexBuffer = indexBuffer; - if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer)); - } else { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + BufferPointer indexBuffer = batch._buffers.get(batch._params[paramOffset + 1]._uint); + if (indexBuffer != _input._indexBuffer) { + _input._indexBuffer = indexBuffer; + if (indexBuffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer)); + } else { + // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } (void) CHECK_GL_ERROR(); } -template -void popParam(Batch::Params& params, uint32& paramOffset, V& v) { - for (size_t i = 0; i < v.length(); ++i) { - v[i] = params[paramOffset++]._float; +void GLBackend::do_setIndirectBuffer(Batch& batch, uint32 paramOffset) { + _input._indirectBufferOffset = batch._params[paramOffset + 1]._uint; + _input._indirectBufferStride = batch._params[paramOffset + 2]._uint; + + BufferPointer buffer = batch._buffers.get(batch._params[paramOffset]._uint); + if (buffer != _input._indirectBuffer) { + _input._indirectBuffer = buffer; + if (buffer) { + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferID(*buffer)); + } else { + // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } + + (void)CHECK_GL_ERROR(); } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 093434f079..5e04fe867f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -87,37 +87,34 @@ void GeometryCache::ShapeData::setupIndices(gpu::BufferPointer& indexBuffer, con void GeometryCache::ShapeData::setupBatch(gpu::Batch& batch) const { batch.setInputBuffer(gpu::Stream::POSITION, _positionView); batch.setInputBuffer(gpu::Stream::NORMAL, _normalView); + batch.setIndexBuffer(gpu::UINT16, _indices, 0); } void GeometryCache::ShapeData::draw(gpu::Batch& batch) const { if (_indexCount) { setupBatch(batch); - batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset); - batch.drawIndexed(gpu::TRIANGLES, _indexCount); + batch.drawIndexed(gpu::TRIANGLES, _indexCount, _indexOffset); } } void GeometryCache::ShapeData::drawWire(gpu::Batch& batch) const { if (_wireIndexCount) { setupBatch(batch); - batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset); - batch.drawIndexed(gpu::LINES, _wireIndexCount); + batch.drawIndexed(gpu::LINES, _wireIndexCount, _wireIndexOffset); } } void GeometryCache::ShapeData::drawInstances(gpu::Batch& batch, size_t count) const { if (_indexCount) { setupBatch(batch); - batch.setIndexBuffer(gpu::UINT16, _indices, _indexOffset); - batch.drawIndexedInstanced(count, gpu::TRIANGLES, _indexCount); + batch.drawIndexedInstanced(count, gpu::TRIANGLES, _indexCount, _indexOffset); } } void GeometryCache::ShapeData::drawWireInstances(gpu::Batch& batch, size_t count) const { if (_wireIndexCount) { setupBatch(batch); - batch.setIndexBuffer(gpu::UINT16, _indices, _wireIndexOffset); - batch.drawIndexedInstanced(count, gpu::LINES, _wireIndexCount); + batch.drawIndexedInstanced(count, gpu::LINES, _wireIndexCount, _wireIndexOffset); } } @@ -323,7 +320,7 @@ void GeometryCache::buildShapes() { 20, 21, 21, 22, 22, 23, 23, 20, // back 0, 23, 1, 22, 2, 21, 3, 20 // sides }; - for (int i = 0; i < wireIndices.size(); ++i) { + for (size_t i = 0; i < wireIndices.size(); ++i) { indices[i] += startingIndex; } @@ -374,7 +371,7 @@ void GeometryCache::buildShapes() { 0, 3, 1, 3, 2, 3, }; - for (int i = 0; i < wireIndices.size(); ++i) { + for (size_t i = 0; i < wireIndices.size(); ++i) { wireIndices[i] += startingIndex; } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 2e0d0a5493..aa1593db78 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -232,14 +232,6 @@ public: /// Set a batch to the simple pipeline, returning the previous pipeline void useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend = false); -private: - GeometryCache(); - virtual ~GeometryCache(); - void buildShapes(); - - typedef QPair IntPair; - typedef QPair VerticesIndices; - struct ShapeData { size_t _indexOffset{ 0 }; size_t _indexCount{ 0 }; @@ -263,7 +255,13 @@ private: VShape _shapes; +private: + GeometryCache(); + virtual ~GeometryCache(); + void buildShapes(); + typedef QPair IntPair; + typedef QPair VerticesIndices; gpu::PipelinePointer _standardDrawPipeline; gpu::PipelinePointer _standardDrawPipelineNoBlend; diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index ad9ed9bb4a..0acbbcd725 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -35,6 +35,7 @@ // Must come after GL headers #include +#include #include #include @@ -101,7 +102,24 @@ float getSeconds(quint64 start = 0) { return seconds; } +struct DrawElementsIndirectCommand { + uint _count{ 0 }; + uint _instanceCount{ 0 }; + uint _firstIndex{ 0 }; + uint _baseVertex{ 0 }; + uint _baseInstance{ 0 }; +}; +static const size_t TYPE_COUNT = 4; +static GeometryCache::Shape SHAPE[TYPE_COUNT] = { + GeometryCache::Icosahedron, + GeometryCache::Cube, + GeometryCache::Sphere, + GeometryCache::Tetrahedron, + //GeometryCache::Line, +}; + +gpu::Stream::FormatPointer& getInstancedSolidStreamFormat(); // Creates an OpenGL window that renders a simple unlit scene using the gpu library and GeometryCache // Should eventually get refactored into something that supports multiple gpu backends. @@ -134,7 +152,7 @@ public: // Qt Quick may need a depth and stencil buffer. Always make sure these are available. format.setDepthBufferSize(16); format.setStencilBufferSize(8); - format.setVersion(4, 1); + format.setVersion(4, 3); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setOption(QSurfaceFormat::DebugContext); format.setSwapInterval(0); @@ -147,6 +165,13 @@ public: show(); makeCurrent(); + QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); + logger->initialize(); // initializes in the current context, i.e. ctx + connect(logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage& message){ + qDebug() << message; + }); + logger->startLogging(QOpenGLDebugLogger::SynchronousLogging); + gpu::Context::init(); _context = std::make_shared(); @@ -177,7 +202,9 @@ public: void draw() { static auto startTime = usecTimestampNow(); - if (!isVisible()) { + // Attempting to draw before we're visible and have a valid size will + // produce GL errors. + if (!isVisible() || _size.width() <= 0 || _size.height() <= 0) { return; } makeCurrent(); @@ -192,7 +219,8 @@ public: glm::vec3 unitscale { 1.0f }; glm::vec3 up { 0.0f, 1.0f, 0.0f }; - glm::vec3 camera_position { 1.5f * sinf(t), 0.0f, 1.5f * cos(t) }; + float distance = 3.0f; + glm::vec3 camera_position{ distance * sinf(t), 0.0f, distance * cos(t) }; static const vec3 camera_focus(0); static const vec3 camera_up(0, 1, 0); @@ -202,57 +230,141 @@ public: batch.setModelTransform(Transform()); auto geometryCache = DependencyManager::get(); - + // Render grid on xz plane (not the optimal way to do things, but w/e) // Note: GeometryCache::renderGrid will *not* work, as it is apparenly unaffected by batch rotations and renders xy only - static const std::string GRID_INSTANCE = "Grid"; - static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f }); - static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f }); - auto transformBuffer = batch.getNamedBuffer(GRID_INSTANCE, 0); - auto colorBuffer = batch.getNamedBuffer(GRID_INSTANCE, 1); - for (int i = 0; i < 100; ++i) { - { - glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i)); - transform = glm::scale(transform, vec3(100, 1, 1)); - transformBuffer->append(transform); - colorBuffer->append(compactColor1); - } + { + static const std::string GRID_INSTANCE = "Grid"; + static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f }); + static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f }); + static gpu::BufferPointer transformBuffer; + static gpu::BufferPointer colorBuffer; + if (!transformBuffer) { + transformBuffer = std::make_shared(); + colorBuffer = std::make_shared(); + for (int i = 0; i < 100; ++i) { + { + glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i)); + transform = glm::scale(transform, vec3(100, 1, 1)); + transformBuffer->append(transform); + colorBuffer->append(compactColor1); + } - { - glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0))); - transform = glm::translate(transform, vec3(0, -1, -50 + i)); - transform = glm::scale(transform, vec3(100, 1, 1)); - transformBuffer->append(transform); - colorBuffer->append(compactColor2); + { + glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0))); + transform = glm::translate(transform, vec3(0, -1, -50 + i)); + transform = glm::scale(transform, vec3(100, 1, 1)); + transformBuffer->append(transform); + colorBuffer->append(compactColor2); + } + } } + + batch.setupNamedCalls(GRID_INSTANCE, 200, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + batch.setViewTransform(camera); + batch.setModelTransform(Transform()); + batch.setPipeline(_pipeline); + batch._glUniform1i(_instanceLocation, 1); + geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data._count, transformBuffer, colorBuffer); + batch._glUniform1i(_instanceLocation, 0); + }); } - batch.setupNamedCalls(GRID_INSTANCE, 200, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + { + static const size_t ITEM_COUNT = 1000; + static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT; + static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT; + + static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; + static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; + static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA }; + static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW }; + + + static std::vector transforms; + static std::vector colors; + static gpu::BufferPointer indirectBuffer; + static gpu::BufferPointer transformBuffer; + static gpu::BufferPointer colorBuffer; + static gpu::BufferView colorView; + static gpu::BufferView instanceXfmView; + + if (!transformBuffer) { + transformBuffer = std::make_shared(); + colorBuffer = std::make_shared(); + indirectBuffer = std::make_shared(); + + static const float ITEM_RADIUS = 20; + static const vec3 ITEM_TRANSLATION{ 0, 0, -ITEM_RADIUS }; + for (size_t i = 0; i < TYPE_COUNT; ++i) { + GeometryCache::Shape shape = SHAPE[i]; + GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape]; + { + DrawElementsIndirectCommand indirectCommand; + indirectCommand._count = shapeData._indexCount; + indirectCommand._instanceCount = ITEM_COUNT; + indirectCommand._baseInstance = i * ITEM_COUNT; + indirectCommand._firstIndex = shapeData._indexOffset / 2; + indirectCommand._baseVertex = 0; + indirectBuffer->append(indirectCommand); + } + + //indirectCommand._count + float startingInterval = ITEM_INTERVAL * i; + for (size_t j = 0; j < ITEM_COUNT; ++j) { + float theta = j * SHAPE_INTERVAL + startingInterval; + auto transform = glm::rotate(mat4(), theta, Vectors::UP); + transform = glm::rotate(transform, (randFloat() - 0.5f) * PI / 4.0f, Vectors::UNIT_X); + transform = glm::translate(transform, ITEM_TRANSLATION); + transform = glm::scale(transform, vec3(randFloat() / 2.0f + 0.5f)); + transformBuffer->append(transform); + transforms.push_back(transform); + auto color = vec4{ randomColorValue(64), randomColorValue(64), randomColorValue(64), 255 }; + color /= 255.0f; + colors.push_back(color); + colorBuffer->append(toCompactColor(color)); + } + } + colorView = gpu::BufferView(colorBuffer, COLOR_ELEMENT); + instanceXfmView = gpu::BufferView(transformBuffer, TRANSFORM_ELEMENT); + } + +#if 1 + GeometryCache::ShapeData shapeData = geometryCache->_shapes[GeometryCache::Icosahedron]; + { + batch.setViewTransform(camera); + batch.setModelTransform(Transform()); + batch.setPipeline(_pipeline); + batch._glUniform1i(_instanceLocation, 1); + batch.setInputFormat(getInstancedSolidStreamFormat()); + batch.setInputBuffer(gpu::Stream::COLOR, colorView); + batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView); + batch.setIndirectBuffer(indirectBuffer); + shapeData.setupBatch(batch); + batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES); + batch._glUniform1i(_instanceLocation, 0); + } +#else batch.setViewTransform(camera); - batch.setModelTransform(Transform()); batch.setPipeline(_pipeline); - auto& xfm = data._buffers[0]; - auto& color = data._buffers[1]; - batch._glUniform1i(_instanceLocation, 1); - geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data._count, xfm, color); - batch._glUniform1i(_instanceLocation, 0); - }); - - + for (size_t i = 0; i < TYPE_COUNT; ++i) { + GeometryCache::Shape shape = SHAPE[i]; + for (size_t j = 0; j < ITEM_COUNT; ++j) { + int index = i * ITEM_COUNT + j; + batch.setModelTransform(transforms[index]); + const vec4& color = colors[index]; + batch._glColor4f(color.r, color.g, color.b, 1.0); + geometryCache->renderShape(batch, shape); + } + } +#endif + } // Render unlit cube + sphere - - static GeometryCache::Shape SHAPE[] = { - GeometryCache::Cube, - GeometryCache::Sphere, - GeometryCache::Tetrahedron, - GeometryCache::Icosahedron, - }; - static auto startUsecs = usecTimestampNow(); float seconds = getSeconds(startUsecs); seconds /= 4.0; - int shapeIndex = ((int)seconds) % 4; + int shapeIndex = ((int)seconds) % TYPE_COUNT; bool wire = seconds - floor(seconds) > 0.5f; batch.setModelTransform(Transform()); batch._glColor4f(0.8f, 0.25f, 0.25f, 1.0f); @@ -263,7 +375,7 @@ public: geometryCache->renderShape(batch, SHAPE[shapeIndex]); } - batch.setModelTransform(Transform().setScale(1.05f)); + batch.setModelTransform(Transform().setScale(2.05f)); batch._glColor4f(1, 1, 1, 1); geometryCache->renderWireCube(batch); From fa1d5be3100a50b18884eddbbb071764d52179f0 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Tue, 22 Sep 2015 18:20:23 -0700 Subject: [PATCH 065/418] Reduce volume, JSLint, Coding standards --- examples/toys/flashlight/createFlashlight.js | 41 ++++-------- examples/toys/flashlight/flashlight.js | 70 +++++++++----------- 2 files changed, 47 insertions(+), 64 deletions(-) diff --git a/examples/toys/flashlight/createFlashlight.js b/examples/toys/flashlight/createFlashlight.js index 38907efa75..7c04433979 100644 --- a/examples/toys/flashlight/createFlashlight.js +++ b/examples/toys/flashlight/createFlashlight.js @@ -11,7 +11,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); @@ -19,31 +19,18 @@ var scriptURL = Script.resolvePath('flashlight.js?123123'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; -var center = Vec3.sum(Vec3.sum(MyAvatar.position, { - x: 0, - y: 0.5, - z: 0 -}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); +var center = Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0, y: 0.5, z: 0}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); var flashlight = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: center, - dimensions: { - x: 0.08, - y: 0.30, - z: 0.08 - }, - collisionsWillMove: true, - shapeType: 'box', - script: scriptURL -}); - - -function cleanup() { - //commenting out the line below makes this persistent. to delete at cleanup, uncomment - //Entities.deleteEntity(flashlight); -} - - -Script.scriptEnding.connect(cleanup); \ No newline at end of file + type: "Model", + modelURL: modelURL, + position: center, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, + collisionsWillMove: true, + shapeType: 'box', + script: scriptURL +}); \ No newline at end of file diff --git a/examples/toys/flashlight/flashlight.js b/examples/toys/flashlight/flashlight.js index 5afaed829c..5563001d07 100644 --- a/examples/toys/flashlight/flashlight.js +++ b/examples/toys/flashlight/flashlight.js @@ -14,20 +14,18 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -(function() { +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +(function () { Script.include("../../libraries/utils.js"); var ON_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; var OFF_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_off.wav'; - var _this; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - Flashlight = function() { - _this = this; - }; + function Flashlight() { + return; + } //if the trigger value goes below this while held, the flashlight will turn off. if it goes above, it will var DISABLE_LIGHT_THRESHOLD = 0.7; @@ -48,7 +46,7 @@ x: 0, y: -0.1, z: 0 - } + }; // Evaluate the world light entity positions and orientations from the model ones function evalLightWorldTransform(modelPos, modelRot) { @@ -57,14 +55,14 @@ p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) }; - }; + } function glowLightWorldTransform(modelPos, modelRot) { return { p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, GLOW_LIGHT_POSITION)), q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) }; - }; + } Flashlight.prototype = { @@ -73,13 +71,13 @@ whichHand: null, hasSpotlight: false, spotlight: null, - setRightHand: function() { + setRightHand: function () { this.hand = 'RIGHT'; }, - setLeftHand: function() { + setLeftHand: function () { this.hand = 'LEFT'; }, - startNearGrab: function() { + startNearGrab: function () { if (!this.hasSpotlight) { //this light casts the beam @@ -125,10 +123,10 @@ } }, - setWhichHand: function() { + setWhichHand: function () { this.whichHand = this.hand; }, - continueNearGrab: function() { + continueNearGrab: function () { if (this.whichHand === null) { //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); @@ -137,7 +135,7 @@ this.changeLightWithTriggerPressure(this.whichHand); } }, - releaseGrab: function() { + releaseGrab: function () { //delete the lights and reset state if (this.hasSpotlight) { Entities.deleteEntity(this.spotlight); @@ -149,7 +147,7 @@ this.lightOn = false; } }, - updateLightPositions: function() { + updateLightPositions: function () { var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); //move the two lights along the vectors we set above @@ -161,16 +159,16 @@ Entities.editEntity(this.spotlight, { position: lightTransform.p, rotation: lightTransform.q, - }) + }); Entities.editEntity(this.glowLight, { position: glowLightTransform.p, rotation: glowLightTransform.q, - }) + }); }, - changeLightWithTriggerPressure: function(flashLightHand) { + changeLightWithTriggerPressure: function (flashLightHand) { var handClickString = flashLightHand + "_HAND_CLICK"; @@ -183,9 +181,9 @@ } else if (this.triggerValue >= DISABLE_LIGHT_THRESHOLD && this.lightOn === false) { this.turnLightOn(); } - return + return; }, - turnLightOff: function() { + turnLightOff: function () { this.playSoundAtCurrentPosition(false); Entities.editEntity(this.spotlight, { intensity: 0 @@ -193,11 +191,9 @@ Entities.editEntity(this.glowLight, { intensity: 0 }); - this.lightOn = false - - + this.lightOn = false; }, - turnLightOn: function() { + turnLightOn: function () { this.playSoundAtCurrentPosition(true); Entities.editEntity(this.glowLight, { @@ -206,35 +202,35 @@ Entities.editEntity(this.spotlight, { intensity: 2 }); - this.lightOn = true + this.lightOn = true; }, // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: // * remembering our entityID, so we can access it in cases where we're called without an entityID - preload: function(entityID) { + preload: function (entityID) { this.entityID = entityID; this.ON_SOUND = SoundCache.getSound(ON_SOUND_URL); this.OFF_SOUND = SoundCache.getSound(OFF_SOUND_URL); }, - playSoundAtCurrentPosition: function(playOnSound) { + playSoundAtCurrentPosition: function (playOnSound) { var position = Entities.getEntityProperties(this.entityID, "position").position; var audioProperties = { - volume: 0.5, + volume: 0.25, position: position - } - if (playOnSound) { - Audio.playSound(this.ON_SOUND, audioProperties) - } else { - Audio.playSound(this.OFF_SOUND, audioProperties) + }; + if (playOnSound) { + Audio.playSound(this.ON_SOUND, audioProperties); + } else { + Audio.playSound(this.OFF_SOUND, audioProperties); } }, // unload() will be called when our entity is no longer available. It may be because we were deleted, // or because we've left the domain or quit the application. - unload: function(entityID) { + unload: function () { if (this.hasSpotlight) { Entities.deleteEntity(this.spotlight); @@ -252,4 +248,4 @@ // entity scripts always need to return a newly constructed object of our type return new Flashlight(); -}) \ No newline at end of file +}); \ No newline at end of file From d53295655f786bd5e78958d1e99adf7bbecad1b2 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 22 Sep 2015 19:54:51 -0700 Subject: [PATCH 066/418] Fixes for empty poses This can happen when an animation is evaluated before it is finished loading. --- libraries/animation/src/AnimManipulator.cpp | 6 ++++++ libraries/animation/src/AnimStateMachine.cpp | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimManipulator.cpp b/libraries/animation/src/AnimManipulator.cpp index 0640c418e3..8b9089f450 100644 --- a/libraries/animation/src/AnimManipulator.cpp +++ b/libraries/animation/src/AnimManipulator.cpp @@ -29,6 +29,12 @@ const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, flo const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { _alpha = animVars.lookup(_alphaVar, _alpha); + _poses = underPoses; + + if (underPoses.size() == 0) { + return _poses; + } + for (auto& jointVar : _jointVars) { if (!jointVar.hasPerformedJointLookup) { jointVar.jointIndex = _skeleton->nameToJointIndex(jointVar.jointName); diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 8ce0fc95b0..758067343d 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -52,7 +52,7 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, fl if (_duringInterp) { _alpha += _alphaVel * dt; if (_alpha < 1.0f) { - if (_poses.size() > 0) { + if (_poses.size() > 0 && _nextPoses.size() > 0 && _prevPoses.size() > 0) { ::blend(_poses.size(), &_prevPoses[0], &_nextPoses[0], _alpha, &_poses[0]); } } else { @@ -77,8 +77,6 @@ void AnimStateMachine::addState(State::Pointer state) { void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointer desiredState) { - qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID(); - const float FRAMES_PER_SECOND = 30.0f; auto prevStateNode = _currentState->getNode(); @@ -96,6 +94,8 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, State::Pointe Triggers triggers; _nextPoses = nextStateNode->evaluate(animVars, dt, triggers); + qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget; + _currentState = desiredState; } From d04f4d4b2b72fb2df5432f971c630012163edf0e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 22 Sep 2015 19:57:23 -0700 Subject: [PATCH 067/418] Added shared DebugDraw singleton. --- interface/src/avatar/MyAvatar.cpp | 4 ++ libraries/render-utils/src/AnimDebugDraw.cpp | 44 +++++++++------- libraries/render-utils/src/AnimDebugDraw.h | 6 --- libraries/shared/src/DebugDraw.cpp | 40 ++++++++++++++ libraries/shared/src/DebugDraw.h | 55 ++++++++++++++++++++ 5 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 libraries/shared/src/DebugDraw.cpp create mode 100644 libraries/shared/src/DebugDraw.h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4bbd0a4a0b..b2df29d464 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -47,6 +47,7 @@ #include "Recorder.h" #include "Util.h" #include "InterfaceLogging.h" +#include "DebugDraw.h" using namespace std; @@ -1358,6 +1359,9 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { } } + DebugDraw::getInstance().updateMyAvatarPos(getPosition()); + DebugDraw::getInstance().updateMyAvatarRot(getOrientation()); + if (shouldDrawHead != _prevShouldDrawHead) { _skeletonModel.setCauterizeBones(!shouldDrawHead); } diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 1e6428b50f..e7dc75dd57 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -13,6 +13,7 @@ #include "AbstractViewStateInterface.h" #include "RenderUtilsLogging.h" #include "GLMHelpers.h" +#include "DebugDraw.h" #include "AnimDebugDraw.h" @@ -67,13 +68,9 @@ namespace render { } } -static AnimDebugDraw* instance = nullptr; - AnimDebugDraw& AnimDebugDraw::getInstance() { - if (!instance) { - instance = new AnimDebugDraw(); - } - return *instance; + static AnimDebugDraw instance; + return instance; } static uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { @@ -176,14 +173,6 @@ void AnimDebugDraw::removePoses(const std::string& key) { _poses.erase(key); } -void AnimDebugDraw::addPose(const std::string& key, const AnimPose& pose, const AnimPose& rootPose) { - _singlePoses[key] = SinglePoseInfo(pose, rootPose); -} - -void AnimDebugDraw::removePose(const std::string& key) { - _singlePoses.erase(key); -} - static const uint32_t red = toRGBA(255, 0, 0, 255); static const uint32_t green = toRGBA(0, 255, 0, 255); static const uint32_t blue = toRGBA(0, 0, 255, 255); @@ -380,7 +369,11 @@ void AnimDebugDraw::update() { } } - numVerts += _singlePoses.size() * VERTICES_PER_BONE; + // count marker verts from shared DebugDraw singleton + auto markerMap = DebugDraw::getInstance().getMarkerMap(); + numVerts += markerMap.size() * VERTICES_PER_BONE; + auto myAvatarMarkerMap = DebugDraw::getInstance().getMyAvatarMarkerMap(); + numVerts += myAvatarMarkerMap.size() * VERTICES_PER_BONE; data._vertexBuffer->resize(sizeof(Vertex) * numVerts); Vertex* verts = (Vertex*)data._vertexBuffer->editData(); @@ -486,11 +479,22 @@ void AnimDebugDraw::update() { } } - for (auto& iter : _singlePoses) { - AnimPose pose = std::get<0>(iter.second); - AnimPose rootPose = std::get<1>(iter.second); - const float radius = POSE_RADIUS / (pose.scale.x * rootPose.scale.x); - addBone(rootPose, pose, radius, v); + // draw markers from shared DebugDraw singleton + for (auto& iter : markerMap) { + glm::quat rot = std::get<0>(iter.second); + glm::vec3 pos = std::get<1>(iter.second); + glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. + const float radius = POSE_RADIUS; + addBone(AnimPose::identity, AnimPose(glm::vec3(1), rot, pos), radius, v); + } + + AnimPose myAvatarPose(glm::vec3(1), DebugDraw::getInstance().getMyAvatarRot(), DebugDraw::getInstance().getMyAvatarPos()); + for (auto& iter : myAvatarMarkerMap) { + glm::quat rot = std::get<0>(iter.second); + glm::vec3 pos = std::get<1>(iter.second); + glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. + const float radius = POSE_RADIUS; + addBone(myAvatarPose, AnimPose(glm::vec3(1), rot, pos), radius, v); } assert(numVerts == (v - verts)); diff --git a/libraries/render-utils/src/AnimDebugDraw.h b/libraries/render-utils/src/AnimDebugDraw.h index 5bb19097f2..c2205c1afe 100644 --- a/libraries/render-utils/src/AnimDebugDraw.h +++ b/libraries/render-utils/src/AnimDebugDraw.h @@ -39,10 +39,6 @@ public: void addPoses(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPoseVec& poses, const AnimPose& rootPose, const glm::vec4& color); void removePoses(const std::string& key); - // draw a single pose - void addPose(const std::string& key, const AnimPose& rootPose, const AnimPose& pose); - void removePose(const std::string& key); - void update(); protected: @@ -55,12 +51,10 @@ protected: typedef std::tuple SkeletonInfo; typedef std::tuple AnimNodeInfo; typedef std::tuple PosesInfo; - typedef std::tuple SinglePoseInfo; std::unordered_map _skeletons; std::unordered_map _animNodes; std::unordered_map _poses; - std::unordered_map _singlePoses; // no copies AnimDebugDraw(const AnimDebugDraw&) = delete; diff --git a/libraries/shared/src/DebugDraw.cpp b/libraries/shared/src/DebugDraw.cpp new file mode 100644 index 0000000000..3060e151c8 --- /dev/null +++ b/libraries/shared/src/DebugDraw.cpp @@ -0,0 +1,40 @@ +// +// DebugDraw.cpp +// +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "DebugDraw.h" + +DebugDraw& DebugDraw::getInstance() { + static DebugDraw instance; + return instance; +} + +DebugDraw::DebugDraw() { + +} + +DebugDraw::~DebugDraw() { + +} + +void DebugDraw::addMarker(const std::string& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color) { + _markers[key] = MarkerInfo(rotation, position, color); +} + +void DebugDraw::removeMarker(const std::string& key) { + _markers.erase(key); +} + +void DebugDraw::addMyAvatarMarker(const std::string& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color) { + _myAvatarMarkers[key] = MarkerInfo(rotation, position, color); +} + +void DebugDraw::removeMyAvatarMarker(const std::string& key) { + _myAvatarMarkers.erase(key); +} + diff --git a/libraries/shared/src/DebugDraw.h b/libraries/shared/src/DebugDraw.h new file mode 100644 index 0000000000..2f62f17abf --- /dev/null +++ b/libraries/shared/src/DebugDraw.h @@ -0,0 +1,55 @@ +// +// DebugDraw.h +// +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_DebugDraw_h +#define hifi_DebugDraw_h + +#include +#include +#include +#include +#include + +class DebugDraw { +public: + static DebugDraw& getInstance(); + + DebugDraw(); + ~DebugDraw(); + + // world space maker + void addMarker(const std::string& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color); + void removeMarker(const std::string& key); + + // myAvatar relative marker + void addMyAvatarMarker(const std::string& key, const glm::quat& rotation, const glm::vec3& position, const glm::vec4& color); + void removeMyAvatarMarker(const std::string& key); + + using MarkerInfo = std::tuple; + using MarkerMap = std::unordered_map; + + // + // accessors used by renderer + // + + const MarkerMap& getMarkerMap() const { return _markers; } + const MarkerMap& getMyAvatarMarkerMap() const { return _myAvatarMarkers; } + void updateMyAvatarPos(const glm::vec3& pos) { _myAvatarPos = pos; } + const glm::vec3& getMyAvatarPos() const { return _myAvatarPos; } + void updateMyAvatarRot(const glm::quat& rot) { _myAvatarRot = rot; } + const glm::quat& getMyAvatarRot() const { return _myAvatarRot; } + +protected: + MarkerMap _markers; + MarkerMap _myAvatarMarkers; + glm::quat _myAvatarRot; + glm::vec3 _myAvatarPos; +}; + +#endif // hifi_DebugDraw_h From 9ce43a57f19816e580de0964107e4d903682cfe4 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 22 Sep 2015 19:58:21 -0700 Subject: [PATCH 068/418] Better head IK when in an HMD. Because the current IK system doesn't quite handle what we need for the head and neck IK, we do it procedurally in the rig, and manually set both neck and head IK targets. --- interface/src/avatar/SkeletonModel.cpp | 34 ++++++++--- libraries/animation/src/Rig.cpp | 79 +++++++++++++++++++++++--- tests/animation/src/data/avatar.json | 5 ++ 3 files changed, 102 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 6b56e92d80..9aa83e453c 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -21,6 +21,7 @@ #include "SkeletonModel.h" #include "Util.h" #include "InterfaceLogging.h" +#include "AnimDebugDraw.h" SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent, RigPointer rig) : Model(rig, parent), @@ -126,19 +127,36 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { headParams.leanSideways = head->getFinalLeanSideways(); headParams.leanForward = head->getFinalLeanForward(); headParams.torsoTwist = head->getTorsoTwist(); - headParams.localHeadOrientation = head->getFinalOrientationInLocalFrame(); headParams.localHeadPitch = head->getFinalPitch(); headParams.localHeadYaw = head->getFinalYaw(); headParams.localHeadRoll = head->getFinalRoll(); - headParams.isInHMD = qApp->getAvatarUpdater()->isHMDMode(); - // get HMD position from sensor space into world space, and back into model space - glm::mat4 worldToModel = glm::inverse(createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition())); - glm::vec3 yAxis(0.0f, 1.0f, 0.0f); - glm::vec3 hmdPosition = glm::angleAxis((float)M_PI, yAxis) * transformPoint(worldToModel * myAvatar->getSensorToWorldMatrix(), myAvatar->getHMDSensorPosition()); - headParams.localHeadPosition = hmdPosition; - headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); + if (qApp->getAvatarUpdater()->isHMDMode()) { + headParams.isInHMD = true; + + // get HMD position from sensor space into world space, and back into model space + AnimPose avatarToWorld(glm::vec3(1), myAvatar->getOrientation(), myAvatar->getPosition()); + glm::mat4 worldToAvatar = (glm::mat4)avatarToWorld.inverse(); + glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + glm::mat4 hmdMat = worldToAvatar * worldHMDMat; + + // in local avatar space (i.e. relative to avatar pos/orientation.) + glm::vec3 hmdPosition = extractTranslation(hmdMat); + glm::quat hmdOrientation = extractRotation(hmdMat); + + headParams.localHeadPosition = hmdPosition; + headParams.localHeadOrientation = hmdOrientation; + + headParams.worldHeadOrientation = extractRotation(worldHMDMat); + } else { + headParams.isInHMD = false; + + // We don't have a valid localHeadPosition. + headParams.localHeadOrientation = head->getFinalOrientationInLocalFrame(); + headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); + } + headParams.eyeLookAt = head->getLookAtPosition(); headParams.eyeSaccade = head->getSaccade(); headParams.leanJointIndex = geometry.leanJointIndex; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index b0ffd081c2..27bfb35787 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -14,9 +14,11 @@ #include #include +#include "NumericalConstants.h" #include "AnimationHandle.h" #include "AnimationLogging.h" #include "AnimSkeleton.h" +#include "DebugDraw.h" #include "Rig.h" @@ -983,19 +985,80 @@ void Rig::updateLeanJoint(int index, float leanSideways, float leanForward, floa } } } +static void hmdHeadNeckModel(AnimSkeleton::ConstPointer skeleton, const glm::vec3& hmdPosition, const glm::quat& origHMDOrientation, + glm::vec3& headPositionOut, glm::quat& headOrientationOut, + glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) { + + // hmd orientation comes in as -z forward, we need z forward for the translations to work correctly. + glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + glm::quat hmdOrientation = origHMDOrientation * rotY180; + + // TODO: cache jointIndices + // Use absolute bindPose positions just in case the relBindPose have rotations we don't expect. + glm::vec3 absRightEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("RightEye")).trans; + glm::vec3 absLeftEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("LeftEye")).trans; + glm::vec3 absHeadPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Head")).trans; + glm::vec3 absNeckPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Neck")).trans; + + glm::vec3 absCenterEyePos = (absRightEyePos + absLeftEyePos) / 2.0f; + glm::vec3 eyeOffset = absCenterEyePos - absHeadPos; + glm::vec3 headOffset = absHeadPos - absNeckPos; + + // apply simplistic head/neck model + + // head + headPositionOut = hmdPosition - hmdOrientation * eyeOffset; + headOrientationOut = hmdOrientation; + + // neck + neckPositionOut = hmdPosition - hmdOrientation * (headOffset + eyeOffset); + + // slerp between bind orientation and hmdOrientation + neckOrientationOut = safeMix(hmdOrientation, skeleton->getRelativeBindPose(skeleton->nameToJointIndex("Neck")).rot, 0.5f); +} void Rig::updateNeckJoint(int index, const HeadParameters& params) { if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { if (_enableAnimGraph && _animSkeleton) { - // the params.localHeadOrientation is composed incorrectly, so re-compose it correctly from pitch, yaw and roll. - glm::quat realLocalHeadOrientation = (glm::angleAxis(glm::radians(-params.localHeadRoll), Z_AXIS) * - glm::angleAxis(glm::radians(params.localHeadYaw), Y_AXIS) * - glm::angleAxis(glm::radians(-params.localHeadPitch), X_AXIS)); - _animVars.set("headRotation", realLocalHeadOrientation); - // There's a theory that when not in hmd, we should _animVars.unset("headPosition"). - // However, until that works well, let's always request head be positioned where requested by hmd, camera, or default. - _animVars.set("headPosition", params.localHeadPosition); + if (params.isInHMD) { + glm::vec3 headPos, neckPos; + glm::quat headRot, neckRot; + + // the input hmd values are in avatar space + // apply rotY180 to values to get them into bone space which has z forward. + glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + glm::vec3 hmdPos = rotY180 * params.localHeadPosition; + glm::quat hmdRot = rotY180 * params.localHeadOrientation; + hmdHeadNeckModel(_animSkeleton, hmdPos, hmdRot, headPos, headRot, neckPos, neckRot); + + // debug rendering + /* + // apply rotY180 again to transform into avatar space. + glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); + glm::vec4 green(0.0f, 1.0f, 0.0f, 1.0f); + DebugDraw::getInstance().addMyAvatarMarker("headTarget", rotY180 * headRot, rotY180 * headPos, red); + DebugDraw::getInstance().addMyAvatarMarker("neckTarget", rotY180 * neckRot, rotY180 * neckPos, green); + */ + + _animVars.set("headPosition", headPos); + _animVars.set("headRotation", headRot); + _animVars.set("neckPosition", neckPos); + _animVars.set("neckRotation", neckRot); + + } else { + + // the params.localHeadOrientation is composed incorrectly, so re-compose it correctly from pitch, yaw and roll. + glm::quat realLocalHeadOrientation = (glm::angleAxis(glm::radians(-params.localHeadRoll), Z_AXIS) * + glm::angleAxis(glm::radians(params.localHeadYaw), Y_AXIS) * + glm::angleAxis(glm::radians(-params.localHeadPitch), X_AXIS)); + + _animVars.unset("headPosition"); + _animVars.set("headRotation", realLocalHeadOrientation); + _animVars.unset("neckPosition"); + _animVars.unset("neckRotation"); + } + } else if (!_enableAnimGraph) { auto& state = _jointStates[index]; diff --git a/tests/animation/src/data/avatar.json b/tests/animation/src/data/avatar.json index 9c357ac845..550a95e980 100644 --- a/tests/animation/src/data/avatar.json +++ b/tests/animation/src/data/avatar.json @@ -23,6 +23,11 @@ "positionVar": "leftHandPosition", "rotationVar": "leftHandRotation" }, + { + "jointName": "Neck", + "positionVar": "neckPosition", + "rotationVar": "neckRotation" + }, { "jointName": "Head", "positionVar": "headPosition", From cf701095c4457096c8726bcfa8d228142c0c7c76 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 09:33:02 -0700 Subject: [PATCH 069/418] updated light switch sound volume to be 50% of what it was --- examples/toybox/entityScripts/lightSwitch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 089e532400..20c11fe721 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -53,7 +53,7 @@ } Audio.playSound(this.switchSound, { - volume: 1, + volume: 0.5, position: this.position }); From 9d9de61afa8a215bbed70b32d0f416b3ffcaaeb8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 09:36:30 -0700 Subject: [PATCH 070/418] updated die starting positions --- examples/toybox/masterResetEntity.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index ed1d3727f1..9355f01419 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -143,9 +143,9 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 540.74, - y: 496, - z: 509.21 + x: 540.92, + y: 494.96, + z: 509.8 }, dimensions: { x: 0.09, @@ -168,9 +168,9 @@ function createDice() { var dice1 = Entities.addEntity(diceProps); diceProps.position = { - x: 540.99, - y: 496, - z: 509.08 + x: 541.03, + y: 494.96, + z: 509.25 }; var dice2 = Entities.addEntity(diceProps); From 573cdc5271396bf29ed3a84137142b07bd48056f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 10:07:59 -0700 Subject: [PATCH 071/418] Added another light switch- the garage light switch controls the three lights closest to it, and hallway light controls the two near hall --- .../{lightSwitch.js => lightSwitchGarage.js} | 66 +------- .../toybox/entityScripts/lightSwitchHall.js | 158 ++++++++++++++++++ examples/toybox/masterResetEntity.js | 51 ++++-- 3 files changed, 207 insertions(+), 68 deletions(-) rename examples/toybox/entityScripts/{lightSwitch.js => lightSwitchGarage.js} (76%) create mode 100644 examples/toybox/entityScripts/lightSwitchHall.js diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitchGarage.js similarity index 76% rename from examples/toybox/entityScripts/lightSwitch.js rename to examples/toybox/entityScripts/lightSwitchGarage.js index 20c11fe721..090e1260bf 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitchGarage.js @@ -18,7 +18,7 @@ // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - LightSwitch = function() { + LightSwitchGarage = function() { _this = this; this.lightStateKey = "lightStateKey"; @@ -28,7 +28,7 @@ }; - LightSwitch.prototype = { + LightSwitchGarage.prototype = { clickReleaseOnEntity: function(entityId, mouseEvent) { if (!mouseEvent.isLeftButton) { @@ -64,7 +64,7 @@ var self = this; entities.forEach(function(entity) { var resetData = getEntityCustomData(self.resetKey, entity, {}) - if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { + if (resetData.resetMe === true && resetData.lightType === "Sconce Light Garage") { Entities.deleteEntity(entity); } }); @@ -75,57 +75,7 @@ }, createLights: function() { - var sconceLight1 = Entities.addEntity({ - type: "Light", - position: { - x: 543.62, - y: 496.24, - z: 511.23 - }, - name: "Sconce 1 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight1, { - resetMe: true, - lightType: "Sconce Light" - }); - - var sconceLight2 = Entities.addEntity({ - type: "Light", - position: { - x: 539.87, - y: 496.24, - z: 505.77 - }, - name: "Sconce 2 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight2, { - resetMe: true, - lightType: "Sconce Light" - }); + var sconceLight3 = Entities.addEntity({ type: "Light", @@ -151,7 +101,7 @@ setEntityCustomData(this.resetKey, sconceLight3, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); var sconceLight4 = Entities.addEntity({ @@ -178,7 +128,7 @@ setEntityCustomData(this.resetKey, sconceLight4, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); var sconceLight5 = Entities.addEntity({ @@ -204,7 +154,7 @@ setEntityCustomData(this.resetKey, sconceLight5, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); @@ -236,5 +186,5 @@ }; // entity scripts always need to return a newly constructed object of our type - return new LightSwitch(); + return new LightSwitchGarage(); }) \ No newline at end of file diff --git a/examples/toybox/entityScripts/lightSwitchHall.js b/examples/toybox/entityScripts/lightSwitchHall.js new file mode 100644 index 0000000000..356dee928c --- /dev/null +++ b/examples/toybox/entityScripts/lightSwitchHall.js @@ -0,0 +1,158 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + LightSwitchHall = function() { + _this = this; + + this.lightStateKey = "lightStateKey"; + this.resetKey = "resetMe"; + + this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); + + }; + + LightSwitchHall.prototype = { + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.toggleLights(); + }, + + startNearTouch: function() { + this.toggleLights(); + }, + + toggleLights: function() { + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (lightState.on === true) { + this.clearLights(); + } else if (lightState.on === false) { + this.createLights(); + } + + Audio.playSound(this.switchSound, { + volume: 0.5, + position: this.position + }); + + }, + + clearLights: function() { + var entities = Entities.findEntities(MyAvatar.position, 100); + var self = this; + entities.forEach(function(entity) { + var resetData = getEntityCustomData(self.resetKey, entity, {}) + if (resetData.resetMe === true && resetData.lightType === "Sconce Light Hall") { + Entities.deleteEntity(entity); + } + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: false + }); + }, + + createLights: function() { + var sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.75, + y: 496.24, + z: 511.13 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight1, { + resetMe: true, + lightType: "Sconce Light Hall" + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 540.1 , + y: 496.24, + z: 505.57 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight2, { + resetMe: true, + lightType: "Sconce Light Hall" + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: true + }); + + }, + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + preload: function(entityID) { + this.entityID = entityID; + + //The light switch is static, so just cache its position once + this.position = Entities.getEntityProperties(this.entityID, "position").position; + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + + //If light is off, then we create two new lights- at the position of the sconces + if (lightState.on === false) { + this.createLights(); + } + //If lights are on, do nothing! + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new LightSwitchHall(); +}) \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9355f01419..14758fbc73 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -55,11 +55,7 @@ function createAllToys() { }); //Handles toggling of all sconce lights - createLightSwitch({ - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }); + createLightSwitches(); } function deleteAllToys() { @@ -109,15 +105,20 @@ function createFlashlight(position) { } -function createLightSwitch(position) { +function createLightSwitches() { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v2"); - var lightSwitch = Entities.addEntity({ + var scriptURL = Script.resolvePath("entityScripts/lightSwitchHall.js?v1"); + + var lightSwitchHall = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: position, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, rotation: { w: 0.63280689716339111, x: 0.63280689716339111, @@ -131,9 +132,39 @@ function createLightSwitch(position) { } }); - setEntityCustomData(resetKey, lightSwitch, { + setEntityCustomData(resetKey, lightSwitchHall, { resetMe: true }); + + scriptURL = Script.resolvePath("entityScripts/lightSwitchGarage.js?v1"); + + var lightSwitchGarage = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Garage", + script: scriptURL, + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } + }); + + setEntityCustomData(resetKey, lightSwitchGarage, { + resetMe: true + }); + } function createDice() { From 2b902238e73d85142eed36b8b04d666ab025da11 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 23 Sep 2015 10:33:31 -0700 Subject: [PATCH 072/418] Code tidying --- libraries/entities/src/ParticleEffectEntityItem.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index b5ec879f61..9958c0ac1e 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -303,11 +303,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch SKIP_ENTITY_PROPERTY(PROP_SPEED_SPREAD, glm::vec3); } } else { - // EMIT_ACCELERATION FAKEOUT - READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - // ACCELERATION_SPREAD FAKEOUT - READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - // ACTUAL PARTICLE_RADIUS + // OLD PROP_EMIT_ACCELERATION FAKEOUT + SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float); + // OLD PROP_ACCELERATION_SPREAD FAKEOUT + SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float); READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); } From 8feabdb51805b6eed3f2108e670954a793c457e1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 10:54:56 -0700 Subject: [PATCH 073/418] adding cat, modified dice positions --- examples/toybox/masterResetEntity.js | 47 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 14758fbc73..b3ef69b294 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -54,6 +54,12 @@ function createAllToys() { z: 506.1 }); + createCat({ + x: 551.107421875, + y: 494.60513305664062, + z: 503.1910400390625 + }) + //Handles toggling of all sconce lights createLightSwitches(); } @@ -70,6 +76,32 @@ function deleteAllToys() { }) } +function createCat(position) { + var scriptURL = Script.resolvePath("entityScripts/cat.js"); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; + var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; + Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "cat", + script: scriptURL, + animationURL: animationURL, + animationIsPlaying: 1, + position: position, + rotation: { + w: 0.9510490894317627, + x: -1.52587890625e-05, + y: 0.30901050567626953, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, + }) +} + function createFlashlight(position) { var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; @@ -174,9 +206,9 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 540.92, + x: 541, y: 494.96, - z: 509.8 + z: 509.1 }, dimensions: { x: 0.09, @@ -199,9 +231,9 @@ function createDice() { var dice1 = Entities.addEntity(diceProps); diceProps.position = { - x: 541.03, + x: 541.05, y: 494.96, - z: 509.25 + z: 509.0 }; var dice2 = Entities.addEntity(diceProps); @@ -289,11 +321,6 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; - var animationSettings = JSON.stringify({ - running: false - }); - var scriptURL = Script.resolvePath("entityScripts/doll.js"); var naturalDimensions = { @@ -306,8 +333,6 @@ function createDoll(position) { type: "Model", name: "doll", modelURL: modelURL, - animationSettings: animationSettings, - animationURL: animationURL, script: scriptURL, position: position, shapeType: 'box', From a45458449618fce479fc5b321b6ce64f73a113a4 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 23 Sep 2015 10:59:52 -0700 Subject: [PATCH 074/418] Updated default avatar-animation.json --- .../meshes/defaultAvatar_full/avatar-animation.json | 5 +++++ libraries/animation/src/AnimNode.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 9c357ac845..550a95e980 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -23,6 +23,11 @@ "positionVar": "leftHandPosition", "rotationVar": "leftHandRotation" }, + { + "jointName": "Neck", + "positionVar": "neckPosition", + "rotationVar": "neckRotation" + }, { "jointName": "Head", "positionVar": "headPosition", diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index d5da552a0f..e8c611d3e4 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -61,7 +61,7 @@ public: // hierarchy accessors void addChild(Pointer child) { _children.push_back(child); } void removeChild(Pointer child); - + Pointer getChild(int i) const; int getChildCount() const { return (int)_children.size(); } From 90a551214e76886c1aaf4deb2cf1cfd632878304 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 23 Sep 2015 11:09:43 -0700 Subject: [PATCH 075/418] Fix for AnimDebugDraw crash on shutdown. --- interface/src/Application.cpp | 2 ++ libraries/render-utils/src/AnimDebugDraw.cpp | 4 ++++ libraries/render-utils/src/AnimDebugDraw.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c359275d8a..18313592aa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -794,6 +794,8 @@ void Application::cleanupBeforeQuit() { DependencyManager::get()->setEnabled(false, true); #endif + AnimDebugDraw::getInstance().shutdown(); + if (_keyboardFocusHighlightID > 0) { getOverlays().deleteOverlay(_keyboardFocusHighlightID); _keyboardFocusHighlightID = -1; diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index e7dc75dd57..2db9094bcb 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -141,6 +141,10 @@ AnimDebugDraw::AnimDebugDraw() : } AnimDebugDraw::~AnimDebugDraw() { +} + +void AnimDebugDraw::shutdown() { + // remove renderItem from main 3d scene. render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene && _itemID) { render::PendingChanges pendingChanges; diff --git a/libraries/render-utils/src/AnimDebugDraw.h b/libraries/render-utils/src/AnimDebugDraw.h index c2205c1afe..ee0e52fe0f 100644 --- a/libraries/render-utils/src/AnimDebugDraw.h +++ b/libraries/render-utils/src/AnimDebugDraw.h @@ -27,6 +27,8 @@ public: AnimDebugDraw(); ~AnimDebugDraw(); + void shutdown(); + // draw a skeleton bind pose void addSkeleton(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color); void removeSkeleton(const std::string& key); From a7facc9f3c428d08f13a7d7beefc21e6709d4bc8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:10:27 -0700 Subject: [PATCH 076/418] Adding a mew sound to cat when user moves hand close --- examples/toybox/entityScripts/cat.js | 58 ++++++++++++++++++++++++++++ examples/toybox/masterResetEntity.js | 15 +++++-- 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 examples/toybox/entityScripts/cat.js diff --git a/examples/toybox/entityScripts/cat.js b/examples/toybox/entityScripts/cat.js new file mode 100644 index 0000000000..573b8997d1 --- /dev/null +++ b/examples/toybox/entityScripts/cat.js @@ -0,0 +1,58 @@ +// +// doll.js +// examples/toybox/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This entity script breathes movement and sound- one might even say life- into a doll. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + Cat = function() { + _this = this; + this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); + + }; + + Cat.prototype = { + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.meow(); + }, + + startNearTouch: function() { + this.meow(); + }, + + meow: function() { + print("PLAYYY") + Audio.playSound(this.meowSound, { + position: this.position, + volume: .1 + }); + }, + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { + this.entityID = entityID; + this.position = Entities.getEntityProperties(this.entityID, "position").position; + } + }; + + // entity scripts always need to return a newly constructed object of our type + return new Cat(); +}); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index b3ef69b294..9ca17eae6b 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -77,16 +77,19 @@ function deleteAllToys() { } function createCat(position) { - var scriptURL = Script.resolvePath("entityScripts/cat.js"); + var scriptURL = Script.resolvePath("entityScripts/cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - Entities.addEntity({ + var animationSettings = JSON.stringify({ + running: true, + }); + var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "cat", script: scriptURL, animationURL: animationURL, - animationIsPlaying: 1, + animationSettings: animationSettings, position: position, rotation: { w: 0.9510490894317627, @@ -99,7 +102,11 @@ function createCat(position) { y: 0.50762706995010376, z: 0.90716040134429932 }, - }) + }); + + setEntityCustomData(resetKey, cat, { + resetMe: true + }); } function createFlashlight(position) { From cc69f518823c7fa3e649271a90c2bac44f824c9e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:30:14 -0700 Subject: [PATCH 077/418] Cat meows when hand is close --- examples/toybox/entityScripts/cat.js | 32 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/examples/toybox/entityScripts/cat.js b/examples/toybox/entityScripts/cat.js index 573b8997d1..3aae7c6391 100644 --- a/examples/toybox/entityScripts/cat.js +++ b/examples/toybox/entityScripts/cat.js @@ -20,25 +20,28 @@ Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - + this.distanceThreshold = 0.5; + this.canMeow = true; + this.meowBreakTime = 3000; }; Cat.prototype = { - clickReleaseOnEntity: function(entityId, mouseEvent) { - if (!mouseEvent.isLeftButton) { - return; + update: function() { + var leftHandPosition = MyAvatar.getLeftPalmPosition(); + var rightHandPosition = MyAvatar.getRightPalmPosition(); + if (Vec3.distance(leftHandPosition, _this.position) < _this.distanceThreshold || Vec3.distance(rightHandPosition, _this.position) < _this.distanceThreshold && _this.canMeow) { + _this.meow(); + _this.canMeow = false; + Script.setTimeout(function() { + _this.canMeow = true + }, _this.meowBreakTime) } - this.meow(); - }, - - startNearTouch: function() { - this.meow(); }, meow: function() { - print("PLAYYY") - Audio.playSound(this.meowSound, { + + Audio.playSound(this.meowSound, { position: this.position, volume: .1 }); @@ -50,9 +53,14 @@ preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; + Script.update.connect(this.update); + }, + + unload: function() { + Script.update.disconnect(this.update); } }; // entity scripts always need to return a newly constructed object of our type return new Cat(); -}); +}); \ No newline at end of file From 9818e2549c36e01e35a1c08ada6d32a99490d7f3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:38:30 -0700 Subject: [PATCH 078/418] handControllerscript is now on par with master --- examples/controllers/handControllerGrab.js | 38 ++++------------------ 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index af1c97da68..251d78e273 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -84,9 +84,7 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_NEAR_TOUCHING = 5; -var STATE_CONTINUE_NEAR_TOUCHING = 6; -var STATE_RELEASE = 7; +var STATE_RELEASE = 5; var GRAB_USER_DATA_KEY = "grabKey"; @@ -127,12 +125,6 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; - case STATE_NEAR_TOUCHING: - this.nearTouching(); - break; - case STATE_CONTINUE_NEAR_TOUCHING: - this.continueNearTouching(); - break; case STATE_RELEASE: this.release(); break; @@ -221,20 +213,19 @@ function controller(hand, triggerAction) { var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); + var props = Entities.getEntityProperties(nearbyEntities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer") { + if (distance < minDistance && props.name !== "pointer" && + props.collisionsWillMove === 1 && + props.locked === 0) { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; } } if (this.grabbedEntity === null) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else if (props.locked === 0 && props.collisionsWillMove === 1) { + } else { this.state = STATE_NEAR_GRABBING; - } else if (props.collisionsWillMove === 0) { - // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event - this.state = STATE_NEAR_TOUCHING; } } } @@ -369,23 +360,6 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } - this.nearTouching = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") - this.state = STATE_CONTINUE_NEAR_TOUCHING; - } - - this.continueNearTouching = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); - } - this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { From 0d7eae2d6416c7adda0ad1838e72e1c54a509363 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 23 Sep 2015 11:42:55 -0700 Subject: [PATCH 079/418] Fix slight translation error when rendering debug animation skeleton. --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b2df29d464..27efb98775 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1334,7 +1334,7 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { // bones are aligned such that z is forward, not -z. glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f)); - AnimPose xform(glm::vec3(1), rotY180 * getOrientation(), getPosition()); + AnimPose xform(glm::vec3(1), getOrientation() * rotY180, getPosition()); if (_enableDebugDrawBindPose && _debugDrawSkeleton) { glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f); From c7cb77a6abf48f28256aa4b50bd5a7e2e88beb77 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:08:28 -0700 Subject: [PATCH 080/418] moved spraycan into toybox folder, and added spraypaint sound --- examples/{ => toybox}/entityScripts/sprayPaintCan.js | 8 ++++++++ examples/toybox/masterResetEntity.js | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) rename examples/{ => toybox}/entityScripts/sprayPaintCan.js (96%) diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/toybox/entityScripts/sprayPaintCan.js similarity index 96% rename from examples/entityScripts/sprayPaintCan.js rename to examples/toybox/entityScripts/sprayPaintCan.js index 29ff451b76..a9538f13c0 100644 --- a/examples/entityScripts/sprayPaintCan.js +++ b/examples/toybox/entityScripts/sprayPaintCan.js @@ -6,6 +6,8 @@ GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; + this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); + var TIP_OFFSET_Z = 0.14; var TIP_OFFSET_Y = 0.04; @@ -101,12 +103,18 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); + + this.sprayInjector = Audio.playSound(this.spraySound, { + position: this.properties.position, + volume: 0.1 + }); } this.letGo = function() { this.activated = false; Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.sprayInjector.stop(); } this.reset = function() { diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9ca17eae6b..836cbb9d9c 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -363,7 +363,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 6bd89f968905e347ff13903d41d1148616a17a0f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:22:18 -0700 Subject: [PATCH 081/418] Toys re-org --- examples/{toybox/entityScripts => toys}/cat.js | 0 examples/{toybox/entityScripts => toys}/doll.js | 0 examples/{toybox/entityScripts => toys}/lightSwitchGarage.js | 0 examples/{toybox/entityScripts => toys}/lightSwitchHall.js | 0 examples/{toybox => toys}/masterResetEntity.js | 0 examples/{toybox/entityScripts => toys}/sprayPaintCan.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename examples/{toybox/entityScripts => toys}/cat.js (100%) rename examples/{toybox/entityScripts => toys}/doll.js (100%) rename examples/{toybox/entityScripts => toys}/lightSwitchGarage.js (100%) rename examples/{toybox/entityScripts => toys}/lightSwitchHall.js (100%) rename examples/{toybox => toys}/masterResetEntity.js (100%) rename examples/{toybox/entityScripts => toys}/sprayPaintCan.js (100%) diff --git a/examples/toybox/entityScripts/cat.js b/examples/toys/cat.js similarity index 100% rename from examples/toybox/entityScripts/cat.js rename to examples/toys/cat.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toys/doll.js similarity index 100% rename from examples/toybox/entityScripts/doll.js rename to examples/toys/doll.js diff --git a/examples/toybox/entityScripts/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js similarity index 100% rename from examples/toybox/entityScripts/lightSwitchGarage.js rename to examples/toys/lightSwitchGarage.js diff --git a/examples/toybox/entityScripts/lightSwitchHall.js b/examples/toys/lightSwitchHall.js similarity index 100% rename from examples/toybox/entityScripts/lightSwitchHall.js rename to examples/toys/lightSwitchHall.js diff --git a/examples/toybox/masterResetEntity.js b/examples/toys/masterResetEntity.js similarity index 100% rename from examples/toybox/masterResetEntity.js rename to examples/toys/masterResetEntity.js diff --git a/examples/toybox/entityScripts/sprayPaintCan.js b/examples/toys/sprayPaintCan.js similarity index 100% rename from examples/toybox/entityScripts/sprayPaintCan.js rename to examples/toys/sprayPaintCan.js From acfb5a32bc0945f02ee4dd77179048563583da3c Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 12:28:46 -0700 Subject: [PATCH 082/418] Rename the nb parameters with num --- libraries/gpu/src/gpu/Batch.cpp | 28 ++++++++++++++-------------- libraries/gpu/src/gpu/Batch.h | 28 +++++++--------------------- 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 15b841dd04..3c787aee2e 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -59,53 +59,53 @@ void Batch::clear() { uint32 Batch::cacheData(uint32 size, const void* data) { uint32 offset = _data.size(); - uint32 nbBytes = size; - _data.resize(offset + nbBytes); + uint32 numBytes = size; + _data.resize(offset + numBytes); memcpy(_data.data() + offset, data, size); return offset; } -void Batch::draw(Primitive primitiveType, uint32 nbVertices, uint32 startVertex) { +void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex) { ADD_COMMAND(draw); _params.push_back(startVertex); - _params.push_back(nbVertices); + _params.push_back(numVertices); _params.push_back(primitiveType); } -void Batch::drawIndexed(Primitive primitiveType, uint32 nbIndices, uint32 startIndex) { +void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) { ADD_COMMAND(drawIndexed); _params.push_back(startIndex); - _params.push_back(nbIndices); + _params.push_back(numIndices); _params.push_back(primitiveType); } -void Batch::drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex, uint32 startInstance) { +void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) { ADD_COMMAND(drawInstanced); _params.push_back(startInstance); _params.push_back(startVertex); - _params.push_back(nbVertices); + _params.push_back(numVertices); _params.push_back(primitiveType); - _params.push_back(nbInstances); + _params.push_back(numInstances); } -void Batch::drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex, uint32 startInstance) { +void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) { ADD_COMMAND(drawIndexedInstanced); _params.push_back(startInstance); _params.push_back(startIndex); - _params.push_back(nbIndices); + _params.push_back(numIndices); _params.push_back(primitiveType); - _params.push_back(nbInstances); + _params.push_back(numInstances); } -void Batch::multiDrawIndirect(uint32 nbCommands, Primitive primitiveType) { +void Batch::multiDrawIndirect(uint32 numCommands, Primitive primitiveType) { ADD_COMMAND(multiDrawIndirect); - _params.push_back(nbCommands); + _params.push_back(numCommands); _params.push_back(primitiveType); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 6dd92739c5..9b74179967 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -93,11 +93,11 @@ public: // Drawcalls void draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0); - void drawIndexed(Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0); - void drawInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbVertices, uint32 startVertex = 0, uint32 startInstance = 0); - void drawIndexedInstanced(uint32 nbInstances, Primitive primitiveType, uint32 nbIndices, uint32 startIndex = 0, uint32 startInstance = 0); - void multiDrawIndirect(uint32 nbCommands, Primitive primitiveType); - void multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType); + void drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex = 0); + void drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex = 0, uint32 startInstance = 0); + void drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex = 0, uint32 startInstance = 0); + void multiDrawIndirect(uint32 numCommands, Primitive primitiveType); + void multiDrawIndexedIndirect(uint32 numCommands, Primitive primitiveType); void setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function); @@ -174,8 +174,6 @@ public: // Reset the stage caches and states void resetStages(); - void runLambda(std::function f); - // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -348,22 +346,10 @@ public: bool _enableSkybox{ false }; protected: + // Maybe useful but shoudln't be public. Please convince me otherwise + void runLambda(std::function f); }; -template -void popVectorParam(Batch::Params& params, uint32& paramOffset, V& v) { - for (size_t i = 0; i < v.length(); ++i) { - v[i] = params[paramOffset++]._float; - } -} - -template -void pushVectorParam(Batch::Params& params, const V& v) { - for (size_t i = 0; i < v.length(); ++i) { - params.push_back(v[i]); - } -} - } #endif From b0923acc2ff5d14f5c4ee9ca827f1d40b97cfa66 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:34:10 -0700 Subject: [PATCH 083/418] Reorg for pathing --- examples/toys/masterResetEntity.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 836cbb9d9c..b8997afe58 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -77,7 +77,7 @@ function deleteAllToys() { } function createCat(position) { - var scriptURL = Script.resolvePath("entityScripts/cat.js?v1"); + var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; var animationSettings = JSON.stringify({ @@ -110,7 +110,7 @@ function createCat(position) { } function createFlashlight(position) { - var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); + var scriptURL = Script.resolvePath('flashlight/flashlight.js'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; var flashlight = Entities.addEntity({ @@ -146,7 +146,7 @@ function createFlashlight(position) { function createLightSwitches() { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitchHall.js?v1"); + var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -175,7 +175,7 @@ function createLightSwitches() { resetMe: true }); - scriptURL = Script.resolvePath("entityScripts/lightSwitchGarage.js?v1"); + scriptURL = Script.resolvePath("lightSwitchGarage.js?v1"); var lightSwitchGarage = Entities.addEntity({ type: "Model", @@ -258,7 +258,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/bubblewand_hotfix_2/examples/toys/bubblewand/wand.js" + var scriptURL = Script.resolvePath("bubblewand/wand.js"); var entity = Entities.addEntity({ name: 'Bubble Wand', @@ -328,7 +328,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("entityScripts/doll.js"); + var scriptURL = Script.resolvePath("doll.js"); var naturalDimensions = { x: 1.63, @@ -363,7 +363,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js"); + var scriptURL = Script.resolvePath("sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 6b468ee87bcd409bd701d1c98af88f7b67f4523e Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 13:10:25 -0700 Subject: [PATCH 084/418] Add the doll --- examples/toys/doll/createDoll.js | 41 +++++++++++ examples/toys/doll/doll.js | 117 +++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 examples/toys/doll/createDoll.js create mode 100644 examples/toys/doll/doll.js diff --git a/examples/toys/doll/createDoll.js b/examples/toys/doll/createDoll.js new file mode 100644 index 0000000000..fef55bd95b --- /dev/null +++ b/examples/toys/doll/createDoll.js @@ -0,0 +1,41 @@ +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ + +function createDoll() { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + var scriptURL = Script.resolvePath("doll.js"); + var center = Vec3.sum(Vec3.sum(MyAvatar.position, { + x: 0, + y: 0.5, + z: 0 + }), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); + + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + var doll = Entities.addEntity({ + type: "Model", + name: "doll", + modelURL: modelURL, + script: scriptURL, + position: center, + shapeType: 'box', + dimensions: desiredDimensions, + gravity: { + x: 0, + y: 0, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + collisionsWillMove: true + }); + return doll; +} + +createDoll(); \ No newline at end of file diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js new file mode 100644 index 0000000000..1417798799 --- /dev/null +++ b/examples/toys/doll/doll.js @@ -0,0 +1,117 @@ +// doll.js +// +// Script Type: Entity +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This entity script breathes movement and sound- one might even say life- into a doll. +// This entity script plays an animation and a sound while you hold +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +(function () { + Script.include("../../utilities.js"); + Script.include("../../libraries/utils.js"); + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + var Doll = function () { + this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; + + }; + + Doll.prototype = { + startAnimationSetting: JSON.stringify({ + running: true, + fps: 30, + startFrame: 0, + lastFrame: 128, + startAutomatically: true + }), + stopAnimationSetting: JSON.stringify({ + running: false, + }), + audioInjector: null, + isGrabbed: false, + leftHand: false, + rightHand: false, + handIsSet: false, + setLeftHand: function () { + if (this.handIsSet === false) { + this.leftHand = true; + this.rightHand = false; + this.setHand = 'left'; + this.handIsSet = true; + } else { + this.currentHand = 'left' + } + }, + setRightHand: function () { + if (this.handIsSet === false) { + this.rightHand = true; + this.leftHand = false; + this.setHand = 'right'; + this.handIsSet = true; + } else { + this.currentHand = 'right' + } + }, + startNearGrab: function () { + if (this.isGrabbed === false) { + Entities.editEntity(this.entityID, { + animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", + animationSettings: this.startAnimationSetting + }); + + var position = Entities.getEntityProperties(this.entityID, "position").position; + this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { + position: position, + volume: 0.1 + }); + this.isGrabbed = true; + } + + }, + continueNearGrab: function () { + if (this.setHand === this.currentHand) { + print('CONTINUING GRAB IN HAND') + var position = Entities.getEntityProperties(this.entityID, "position").position; + this.audioInjector.options.position = position; + }else{ + print('NOT SAME HAND GRABBING') + } + + }, + + releaseGrab: function () { + if (this.isGrabbed === true) { + this.audioInjector.stop(); + Entities.editEntity(this.entityID, { + animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + }); + this.isGrabbed = false; + } + if(this.setHand===this.currentHand){ + print('SAME HAND LET GO') + } + else{ + print('DIFFERENT HAND KEEP HOLDING') + } + + }, + + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * connecting to the update signal so we can check our grabbed state + preload: function (entityID) { + this.entityID = entityID; + + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new Doll(); +}); \ No newline at end of file From ba44390f79fc51ce26c31efb50e5b6d22d450e31 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 13:20:21 -0700 Subject: [PATCH 085/418] Rename touch to grab non colliding --- examples/controllers/handControllerGrab.js | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index af1c97da68..bb806e14f1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -84,10 +84,11 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_NEAR_TOUCHING = 5; -var STATE_CONTINUE_NEAR_TOUCHING = 6; +var STATE_NEAR_GRABBING_NON_COLLIDING = 5; +var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 6; var STATE_RELEASE = 7; + var GRAB_USER_DATA_KEY = "grabKey"; function controller(hand, triggerAction) { @@ -127,11 +128,11 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; - case STATE_NEAR_TOUCHING: - this.nearTouching(); + case STATE_NEAR_GRABBING_NON_COLLIDING: + this.nearGrabbingNonColliding(); break; - case STATE_CONTINUE_NEAR_TOUCHING: - this.continueNearTouching(); + case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: + this.continueNearGrabbingNonColliding(); break; case STATE_RELEASE: this.release(); @@ -233,8 +234,8 @@ function controller(hand, triggerAction) { } else if (props.locked === 0 && props.collisionsWillMove === 1) { this.state = STATE_NEAR_GRABBING; } else if (props.collisionsWillMove === 0) { - // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event - this.state = STATE_NEAR_TOUCHING; + // We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event + this.state = STATE_NEAR_GRABBING_NON_COLLIDING; } } } @@ -369,21 +370,21 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } - this.nearTouching = function() { + this.nearGrabbingNonColliding = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; } - Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") - this.state = STATE_CONTINUE_NEAR_TOUCHING; + Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding") + this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; } - this.continueNearTouching = function() { + this.continueNearGrabNonColliding = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; } - Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabNonColliding"); } From 2c20a12f1300045eb17037d50626dd80cef7ad66 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 13:34:21 -0700 Subject: [PATCH 086/418] refactoring spraypaint to use new events --- examples/toys/sprayPaintCan.js | 107 ++++----------------------------- 1 file changed, 13 insertions(+), 94 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index a9538f13c0..75a2cc10f5 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -21,59 +21,8 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } - } - - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); - } - - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; + this.startNearGrab = function() { + var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -85,7 +34,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: this.properties.position, + position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", emitVelocity: ZERO_VEC, emitAcceleration: ZERO_VEC, @@ -110,30 +59,24 @@ }); } - this.letGo = function() { - this.activated = false; + + this.releaseGrab = function() { Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.painting = false; this.sprayInjector.stop(); } - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC - }); - } - this.sprayStream = function() { - var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); + this.continueNearGrab = function() { + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); + var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + var upVec = Quat.getUp(props.rotation); + var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { + Entities.editEntity(this.paintStream, { position: position, emitVelocity: Vec3.multiply(5, forwardVec) }); @@ -151,8 +94,6 @@ var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation)); this.paint(intersection.intersection, normal); } - - } this.paint = function(position, normal) { @@ -214,40 +155,18 @@ this.preload = function(entityId) { this.strokes = []; - this.activated = false; this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } } this.unload = function() { - Script.update.disconnect(this.update); - if(this.paintStream) { + if (this.paintStream) { Entities.deleteEntity(this.paintStream); } this.strokes.forEach(function(stroke) { Entities.deleteEntity(stroke); }); } - - Script.update.connect(this.update); }); From a2b0e66e13da7f6395ce3361715346d3c3aab3d6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 13:36:00 -0700 Subject: [PATCH 087/418] Sound working for spraypaint --- examples/toys/sprayPaintCan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 75a2cc10f5..40a702762a 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -54,7 +54,7 @@ }); this.sprayInjector = Audio.playSound(this.spraySound, { - position: this.properties.position, + position: position, volume: 0.1 }); } From ef25876c9af0311234d136f830e3c3745961debd Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Sep 2015 14:46:47 -0700 Subject: [PATCH 088/418] implement vector caching for gpu::Batch --- interface/src/Application.cpp | 26 +- interface/src/ui/ApplicationCompositor.cpp | 152 ++-- interface/src/ui/ApplicationOverlay.cpp | 2 + libraries/gpu/src/gpu/Batch.cpp | 26 + libraries/gpu/src/gpu/Batch.h | 46 ++ .../input-plugins/ViveControllerManager.cpp | 29 +- .../src/AmbientOcclusionEffect.cpp | 169 +++-- .../render-utils/src/AntialiasingEffect.cpp | 98 ++- .../src/DeferredLightingEffect.cpp | 658 +++++++++--------- libraries/render-utils/src/HitEffect.cpp | 29 +- .../render-utils/src/RenderDeferredTask.cpp | 106 ++- libraries/render/src/render/DrawStatus.cpp | 54 +- libraries/render/src/render/DrawTask.cpp | 34 +- 13 files changed, 733 insertions(+), 696 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c359275d8a..14d34ba8fa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1033,13 +1033,6 @@ void Application::initializeUi() { updateInputModes(); } -template -void doInBatch(RenderArgs* args, F f) { - gpu::Batch batch; - f(batch); - args->_context->render(batch); -} - void Application::paintGL() { PROFILE_RANGE(__FUNCTION__); if (nullptr == _displayPlugin) { @@ -1093,12 +1086,13 @@ void Application::paintGL() { auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w); auto selfieFbo = DependencyManager::get()->getSelfieFramebuffer(); - gpu::Batch batch; - batch.setFramebuffer(selfieFbo); - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); - batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest); - batch.setFramebuffer(nullptr); - renderArgs._context->render(batch); + doInBatch(&renderArgs, [=](gpu::Batch& batch) { + batch.setFramebuffer(selfieFbo); + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); + batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest); + batch.setFramebuffer(nullptr); + renderArgs._context->render(batch); + }); } } @@ -1286,9 +1280,9 @@ void Application::paintGL() { // Reset the gpu::Context Stages // Back to the default framebuffer; - gpu::Batch batch; - batch.resetStages(); - renderArgs._context->render(batch); + doInBatch(&renderArgs, [=](gpu::Batch& batch) { + batch.resetStages(); + }); } void Application::runTests() { diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index da7a934008..3ff13039f8 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -207,36 +207,36 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { updateTooltips(); //Handle fading and deactivation/activation of UI - gpu::Batch batch; + doInBatch(renderArgs, [=](gpu::Batch& batch) { - auto geometryCache = DependencyManager::get(); + auto geometryCache = DependencyManager::get(); - geometryCache->useSimpleDrawPipeline(batch); - batch.setViewportTransform(renderArgs->_viewport); - batch.setModelTransform(Transform()); - batch.setViewTransform(Transform()); - batch.setProjectionTransform(mat4()); - batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); - geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); + geometryCache->useSimpleDrawPipeline(batch); + batch.setViewportTransform(renderArgs->_viewport); + batch.setModelTransform(Transform()); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(mat4()); + batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); + geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); - // Doesn't actually render - renderPointers(batch); + // Doesn't actually render + renderPointers(batch); - //draw the mouse pointer - // Get the mouse coordinates and convert to NDC [-1, 1] - vec2 canvasSize = qApp->getCanvasSize(); - vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize); - // Invert the Y axis - mousePosition.y *= -1.0f; + //draw the mouse pointer + // Get the mouse coordinates and convert to NDC [-1, 1] + vec2 canvasSize = qApp->getCanvasSize(); + vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize); + // Invert the Y axis + mousePosition.y *= -1.0f; - Transform model; - model.setTranslation(vec3(mousePosition, 0)); - vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize; - model.setScale(vec3(mouseSize, 1.0f)); - batch.setModelTransform(model); - bindCursorTexture(batch); - geometryCache->renderUnitQuad(batch, vec4(1)); - renderArgs->_context->render(batch); + Transform model; + model.setTranslation(vec3(mousePosition, 0)); + vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize; + model.setScale(vec3(mouseSize, 1.0f)); + batch.setModelTransform(model); + bindCursorTexture(batch); + geometryCache->renderUnitQuad(batch, vec4(1)); + }); } @@ -278,75 +278,67 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int auto geometryCache = DependencyManager::get(); - gpu::Batch batch; - geometryCache->useSimpleDrawPipeline(batch); - //batch._glDisable(GL_DEPTH_TEST); - //batch._glDisable(GL_CULL_FACE); - //batch._glBindTexture(GL_TEXTURE_2D, texture); - //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + doInBatch(renderArgs, [=](gpu::Batch& batch) { + geometryCache->useSimpleDrawPipeline(batch); - batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); + batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); - mat4 camMat; - _cameraBaseTransform.getMatrix(camMat); - camMat = camMat * qApp->getEyePose(eye); - batch.setViewportTransform(renderArgs->_viewport); - batch.setViewTransform(camMat); + mat4 camMat; + _cameraBaseTransform.getMatrix(camMat); + camMat = camMat * qApp->getEyePose(eye); + batch.setViewportTransform(renderArgs->_viewport); + batch.setViewTransform(camMat); - batch.setProjectionTransform(qApp->getEyeProjection(eye)); + batch.setProjectionTransform(qApp->getEyeProjection(eye)); -#ifdef DEBUG_OVERLAY - { - batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2))); - geometryCache->renderUnitQuad(batch, glm::vec4(1)); - } -#else - { - //batch.setModelTransform(overlayXfm); + #ifdef DEBUG_OVERLAY + { + batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2))); + geometryCache->renderUnitQuad(batch, glm::vec4(1)); + } + #else + { + batch.setModelTransform(_modelTransform); + drawSphereSection(batch); + } + #endif - batch.setModelTransform(_modelTransform); - drawSphereSection(batch); - } -#endif + // Doesn't actually render + renderPointers(batch); + vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize); - // Doesn't actually render - renderPointers(batch); - vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize); + bindCursorTexture(batch); - bindCursorTexture(batch); + //Controller Pointers + glm::mat4 overlayXfm; + _modelTransform.getMatrix(overlayXfm); - //Controller Pointers - glm::mat4 overlayXfm; - _modelTransform.getMatrix(overlayXfm); + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { + PalmData& palm = myAvatar->getHand()->getPalms()[i]; + if (palm.isActive()) { + glm::vec2 polar = getPolarCoordinates(palm); + // Convert to quaternion + mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); + mat4 reticleXfm = overlayXfm * pointerXfm; + reticleXfm = glm::scale(reticleXfm, reticleScale); + batch.setModelTransform(reticleXfm); + // Render reticle at location + geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); + } + } - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { - PalmData& palm = myAvatar->getHand()->getPalms()[i]; - if (palm.isActive()) { - glm::vec2 polar = getPolarCoordinates(palm); - // Convert to quaternion - mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); + //Mouse Pointer + if (_reticleActive[MOUSE]) { + glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), + _reticlePosition[MOUSE].y())); + mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); mat4 reticleXfm = overlayXfm * pointerXfm; reticleXfm = glm::scale(reticleXfm, reticleScale); batch.setModelTransform(reticleXfm); - // Render reticle at location geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); } - } - - //Mouse Pointer - if (_reticleActive[MOUSE]) { - glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), - _reticlePosition[MOUSE].y())); - mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); - mat4 reticleXfm = overlayXfm * pointerXfm; - reticleXfm = glm::scale(reticleXfm, reticleScale); - batch.setModelTransform(reticleXfm); - geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); - } - - renderArgs->_context->render(batch); + }); } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 7254295c2f..120f97971c 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -94,6 +94,8 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { renderArgs->_context->render(batch); + qDebug() << "ApplicationOverlay::renderOverlay() batch:" << batch.getCacheState(); + renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch CHECK_GL_ERROR(); diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index e6e176be88..62d6a884f3 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -10,6 +10,7 @@ // #include "Batch.h" +#include #include #if defined(NSIGHT_FOUND) @@ -41,7 +42,21 @@ Batch::Batch() : { } +Batch::Batch(const CacheState& cacheState) : Batch() { + _commands.reserve(cacheState.commandsSize); + _commandOffsets.reserve(cacheState.offsetsSize); + _params.reserve(cacheState.paramsSize); + _data.reserve(cacheState.dataSize); +} + +Batch::CacheState Batch::getCacheState() { + return CacheState(_commands.size(), _commandOffsets.size(), _params.size(), _data.size(), + _buffers.size(), _textures.size(), _streamFormats.size(), _transforms.size(), _pipelines.size(), + _framebuffers.size(), _queries.size()); +} + Batch::~Batch() { + //qDebug() << "Batch::~Batch()... " << getCacheState(); } void Batch::clear() { @@ -331,3 +346,14 @@ void Batch::preExecute() { } _namedData.clear(); } + +QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) { + debug << "Batch::CacheState[ " + << "commandsSize:" << cacheState.commandsSize + << "offsetsSize:" << cacheState.offsetsSize + << "paramsSize:" << cacheState.paramsSize + << "dataSize:" << cacheState.dataSize + << "]"; + + return debug; +} diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index ec6fb26c34..44bb7b11a6 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -11,6 +11,8 @@ #ifndef hifi_gpu_Batch_h #define hifi_gpu_Batch_h +#include + #include #include #include @@ -33,6 +35,8 @@ #define PROFILE_RANGE(name) #endif +class QDebug; + namespace gpu { enum ReservedSlot { @@ -70,7 +74,34 @@ public: using NamedBatchDataMap = std::map; + class CacheState { + public: + size_t commandsSize; + size_t offsetsSize; + size_t paramsSize; + size_t dataSize; + + size_t buffersSize; + size_t texturesSize; + size_t streamFormatsSize; + size_t transformsSize; + size_t pipelinesSize; + size_t framebuffersSize; + size_t queriesSize; + + CacheState() : commandsSize(0), offsetsSize(0), paramsSize(0), dataSize(0), buffersSize(0), texturesSize(0), + streamFormatsSize(0), transformsSize(0), pipelinesSize(0), framebuffersSize(0), queriesSize(0) { } + + CacheState(size_t commandsSize, size_t offsetsSize, size_t paramsSize, size_t dataSize, size_t buffersSize, + size_t texturesSize, size_t streamFormatsSize, size_t transformsSize, size_t pipelinesSize, + size_t framebuffersSize, size_t queriesSize) : + commandsSize(commandsSize), offsetsSize(offsetsSize), paramsSize(paramsSize), dataSize(dataSize), + buffersSize(buffersSize), texturesSize(texturesSize), streamFormatsSize(streamFormatsSize), + transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { } + }; + Batch(); + Batch(const CacheState& cacheState); explicit Batch(const Batch& batch); ~Batch(); @@ -78,6 +109,9 @@ public: void preExecute(); + CacheState getCacheState(); + + // Batches may need to override the context level stereo settings // if they're performing framebuffer copy operations, like the // deferred lighting resolution mechanism @@ -276,6 +310,7 @@ public: public: std::vector< Cache > _items; + size_t size() const { return _items.size(); } uint32 cache(const Data& data) { uint32 offset = _items.size(); _items.push_back(Cache(data)); @@ -338,4 +373,15 @@ protected: }; +QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState); + +template +void doInBatch(RenderArgs* args, F f) { + static gpu::Batch::CacheState cacheState; + gpu::Batch batch(cacheState); + f(batch); + args->_context->render(batch); + cacheState = batch.getCacheState(); +} + #endif diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index 4af3dd97d0..3569c76d5d 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -173,23 +173,22 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()]; UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()]; - gpu::Batch batch; - auto geometryCache = DependencyManager::get(); - geometryCache->useSimpleDrawPipeline(batch); - DependencyManager::get()->bindSimpleProgram(batch, true); + doInBatch(args, [=](gpu::Batch& batch) { + auto geometryCache = DependencyManager::get(); + geometryCache->useSimpleDrawPipeline(batch); + DependencyManager::get()->bindSimpleProgram(batch, true); - auto mesh = _modelGeometry.getMesh(); - batch.setInputFormat(mesh->getVertexFormat()); - //batch._glBindTexture(GL_TEXTURE_2D, _uexture); + auto mesh = _modelGeometry.getMesh(); + batch.setInputFormat(mesh->getVertexFormat()); + //batch._glBindTexture(GL_TEXTURE_2D, _uexture); - if (leftHand.isValid()) { - renderHand(leftHand, batch, LEFT_HAND); - } - if (rightHand.isValid()) { - renderHand(rightHand, batch, RIGHT_HAND); - } - - args->_context->render(batch); + if (leftHand.isValid()) { + renderHand(leftHand, batch, LEFT_HAND); + } + if (rightHand.isValid()) { + renderHand(rightHand, batch, RIGHT_HAND); + } + }); } } diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index ebd2053442..35dad58c92 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -178,112 +178,109 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons assert(renderContext->args); assert(renderContext->args->_viewFrustum); - gpu::Batch batch; RenderArgs* args = renderContext->args; - - auto framebufferCache = DependencyManager::get(); - QSize framebufferSize = framebufferCache->getFrameBufferSize(); - float fbWidth = framebufferSize.width(); - float fbHeight = framebufferSize.height(); - float sMin = args->_viewport.x / fbWidth; - float sWidth = args->_viewport.z / fbWidth; - float tMin = args->_viewport.y / fbHeight; - float tHeight = args->_viewport.w / fbHeight; + doInBatch(args, [=](gpu::Batch& batch) { + auto framebufferCache = DependencyManager::get(); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); + float fbWidth = framebufferSize.width(); + float fbHeight = framebufferSize.height(); + float sMin = args->_viewport.x / fbWidth; + float sWidth = args->_viewport.z / fbWidth; + float tMin = args->_viewport.y / fbHeight; + float tHeight = args->_viewport.w / fbHeight; - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); - // Occlusion step - getOcclusionPipeline(); - batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture()); - batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); - _occlusionBuffer->setRenderBuffer(0, _occlusionTexture); - batch.setFramebuffer(_occlusionBuffer); + // Occlusion step + getOcclusionPipeline(); + batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture()); + batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); + _occlusionBuffer->setRenderBuffer(0, _occlusionTexture); + batch.setFramebuffer(_occlusionBuffer); - // Occlusion uniforms - g_scale = 1.0f; - g_bias = 1.0f; - g_sample_rad = 1.0f; - g_intensity = 1.0f; + // Occlusion uniforms + g_scale = 1.0f; + g_bias = 1.0f; + g_sample_rad = 1.0f; + g_intensity = 1.0f; - // Bind the first gpu::Pipeline we need - for calculating occlusion buffer - batch.setPipeline(getOcclusionPipeline()); - batch._glUniform1f(_gScaleLoc, g_scale); - batch._glUniform1f(_gBiasLoc, g_bias); - batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad); - batch._glUniform1f(_gIntensityLoc, g_intensity); + // Bind the first gpu::Pipeline we need - for calculating occlusion buffer + batch.setPipeline(getOcclusionPipeline()); + batch._glUniform1f(_gScaleLoc, g_scale); + batch._glUniform1f(_gBiasLoc, g_bias); + batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad); + batch._glUniform1f(_gIntensityLoc, g_intensity); - // setup uniforms for unpacking a view-space position from the depth buffer - // This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp. - // DeferredBuffer.slh shows how the unpacking is done and what variables are needed. + // setup uniforms for unpacking a view-space position from the depth buffer + // This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp. + // DeferredBuffer.slh shows how the unpacking is done and what variables are needed. - // initialize the view-space unpacking uniforms using frustum data - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; + // initialize the view-space unpacking uniforms using frustum data + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; - args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - float depthScale = (farVal - nearVal) / farVal; - float nearScale = -1.0f / nearVal; - float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + float depthScale = (farVal - nearVal) / farVal; + float nearScale = -1.0f / nearVal; + float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; + float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - // now set the position-unpacking unforms - batch._glUniform1f(_nearLoc, nearVal); - batch._glUniform1f(_depthScaleLoc, depthScale); - batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT); - batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT); + // now set the position-unpacking unforms + batch._glUniform1f(_nearLoc, nearVal); + batch._glUniform1f(_depthScaleLoc, depthScale); + batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT); + batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT); - batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight); - batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight); + batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight); + batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight); - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec2 bottomLeft(-1.0f, -1.0f); - glm::vec2 topRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(0.0f, 0.0f); - glm::vec2 texCoordBottomRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); + glm::vec2 bottomLeft(-1.0f, -1.0f); + glm::vec2 topRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(0.0f, 0.0f); + glm::vec2 texCoordBottomRight(1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - // Vertical blur step - getVBlurPipeline(); - batch.setResourceTexture(0, _occlusionTexture); - _vBlurBuffer->setRenderBuffer(0, _vBlurTexture); - batch.setFramebuffer(_vBlurBuffer); + // Vertical blur step + getVBlurPipeline(); + batch.setResourceTexture(0, _occlusionTexture); + _vBlurBuffer->setRenderBuffer(0, _vBlurTexture); + batch.setFramebuffer(_vBlurBuffer); - // Bind the second gpu::Pipeline we need - for calculating blur buffer - batch.setPipeline(getVBlurPipeline()); + // Bind the second gpu::Pipeline we need - for calculating blur buffer + batch.setPipeline(getVBlurPipeline()); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - // Horizontal blur step - getHBlurPipeline(); - batch.setResourceTexture(0, _vBlurTexture); - _hBlurBuffer->setRenderBuffer(0, _hBlurTexture); - batch.setFramebuffer(_hBlurBuffer); + // Horizontal blur step + getHBlurPipeline(); + batch.setResourceTexture(0, _vBlurTexture); + _hBlurBuffer->setRenderBuffer(0, _hBlurTexture); + batch.setFramebuffer(_hBlurBuffer); - // Bind the third gpu::Pipeline we need - for calculating blur buffer - batch.setPipeline(getHBlurPipeline()); + // Bind the third gpu::Pipeline we need - for calculating blur buffer + batch.setPipeline(getHBlurPipeline()); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - // Blend step - getBlendPipeline(); - batch.setResourceTexture(0, _hBlurTexture); - batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); + // Blend step + getBlendPipeline(); + batch.setResourceTexture(0, _hBlurTexture); + batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); - // Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture - batch.setPipeline(getBlendPipeline()); + // Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture + batch.setPipeline(getBlendPipeline()); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - - // Ready to render - args->_context->render((batch)); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + }); } diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index f337f9b79b..54576b7868 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -100,66 +100,62 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re return; } - gpu::Batch batch; - - batch.enableStereo(false); - RenderArgs* args = renderContext->args; + doInBatch(args, [=](gpu::Batch& batch) { + batch.enableStereo(false); - auto framebufferCache = DependencyManager::get(); - QSize framebufferSize = framebufferCache->getFrameBufferSize(); - float fbWidth = framebufferSize.width(); - float fbHeight = framebufferSize.height(); - // float sMin = args->_viewport.x / fbWidth; - // float sWidth = args->_viewport.z / fbWidth; - // float tMin = args->_viewport.y / fbHeight; - // float tHeight = args->_viewport.w / fbHeight; + auto framebufferCache = DependencyManager::get(); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); + float fbWidth = framebufferSize.width(); + float fbHeight = framebufferSize.height(); + // float sMin = args->_viewport.x / fbWidth; + // float sWidth = args->_viewport.z / fbWidth; + // float tMin = args->_viewport.y / fbHeight; + // float tHeight = args->_viewport.w / fbHeight; - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); - // FXAA step - getAntialiasingPipeline(); - batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); - _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); - batch.setFramebuffer(_antialiasingBuffer); - batch.setPipeline(getAntialiasingPipeline()); + // FXAA step + getAntialiasingPipeline(); + batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); + _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); + batch.setFramebuffer(_antialiasingBuffer); + batch.setPipeline(getAntialiasingPipeline()); - // initialize the view-space unpacking uniforms using frustum data - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; + // initialize the view-space unpacking uniforms using frustum data + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; - args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - // float depthScale = (farVal - nearVal) / farVal; - // float nearScale = -1.0f / nearVal; - // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + // float depthScale = (farVal - nearVal) / farVal; + // float nearScale = -1.0f / nearVal; + // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; + // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); + batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec2 bottomLeft(-1.0f, -1.0f); - glm::vec2 topRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(0.0f, 0.0f); - glm::vec2 texCoordBottomRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); + glm::vec2 bottomLeft(-1.0f, -1.0f); + glm::vec2 topRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(0.0f, 0.0f); + glm::vec2 texCoordBottomRight(1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - // Blend step - getBlendPipeline(); - batch.setResourceTexture(0, _antialiasingTexture); - batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); - batch.setPipeline(getBlendPipeline()); + // Blend step + getBlendPipeline(); + batch.setResourceTexture(0, _antialiasingTexture); + batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer()); + batch.setPipeline(getBlendPipeline()); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); - - // Ready to render - args->_context->render((batch)); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color); + }); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index d23d60cf49..5d079eeec1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -340,341 +340,338 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu } void DeferredLightingEffect::prepare(RenderArgs* args) { - gpu::Batch batch; - batch.enableStereo(false); + doInBatch(args, [=](gpu::Batch& batch) { + batch.enableStereo(false); + batch.setStateScissorRect(args->_viewport); - batch.setStateScissorRect(args->_viewport); + auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); - auto primaryFbo = DependencyManager::get()->getPrimaryFramebuffer(); - - batch.setFramebuffer(primaryFbo); - // clear the normal and specular buffers - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); - const float MAX_SPECULAR_EXPONENT = 128.0f; - batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true); - - args->_context->render(batch); + batch.setFramebuffer(primaryFbo); + // clear the normal and specular buffers + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); + const float MAX_SPECULAR_EXPONENT = 128.0f; + batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true); + }); } gpu::FramebufferPointer _copyFBO; void DeferredLightingEffect::render(RenderArgs* args) { - gpu::Batch batch; - - // Allocate the parameters buffer used by all the deferred shaders - if (!_deferredTransformBuffer[0]._buffer) { - DeferredTransform parameters; - _deferredTransformBuffer[0] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); - _deferredTransformBuffer[1] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); - } - - // Framebuffer copy operations cannot function as multipass stereo operations. - batch.enableStereo(false); - - // perform deferred lighting, rendering to free fbo - auto framebufferCache = DependencyManager::get(); - - QSize framebufferSize = framebufferCache->getFrameBufferSize(); - - // binding the first framebuffer - _copyFBO = framebufferCache->getFramebuffer(); - batch.setFramebuffer(_copyFBO); - - // Clearing it - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); - - // BInd the G-Buffer surfaces - batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); - batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); - batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture()); - batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); - - // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport) - auto monoViewport = args->_viewport; - float sMin = args->_viewport.x / (float)framebufferSize.width(); - float sWidth = args->_viewport.z / (float)framebufferSize.width(); - float tMin = args->_viewport.y / (float)framebufferSize.height(); - float tHeight = args->_viewport.w / (float)framebufferSize.height(); - - // The view frustum is the mono frustum base - auto viewFrustum = args->_viewFrustum; - - // Eval the mono projection - mat4 monoProjMat; - viewFrustum->evalProjectionMatrix(monoProjMat); - - // The mono view transform - Transform monoViewTransform; - viewFrustum->evalViewTransform(monoViewTransform); - - // THe mono view matrix coming from the mono view transform - glm::mat4 monoViewMat; - monoViewTransform.getMatrix(monoViewMat); - - // Running in stero ? - bool isStereo = args->_context->isStereo(); - int numPasses = 1; - - mat4 projMats[2]; - Transform viewTransforms[2]; - ivec4 viewports[2]; - vec4 clipQuad[2]; - vec2 screenBottomLeftCorners[2]; - vec2 screenTopRightCorners[2]; - vec4 fetchTexcoordRects[2]; - - DeferredTransform deferredTransforms[2]; - auto geometryCache = DependencyManager::get(); - - if (isStereo) { - numPasses = 2; - - mat4 eyeViews[2]; - args->_context->getStereoProjections(projMats); - args->_context->getStereoViews(eyeViews); - - float halfWidth = 0.5f * sWidth; - - for (int i = 0; i < numPasses; i++) { - // In stereo, the 2 sides are layout side by side in the mono viewport and their width is half - int sideWidth = monoViewport.z >> 1; - viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); - - deferredTransforms[i].projection = projMats[i]; - - auto sideViewMat = eyeViews[i] * monoViewMat; - viewTransforms[i].evalFromRawMatrix(sideViewMat); - deferredTransforms[i].viewInverse = sideViewMat; - - deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f); - - clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); - screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); - screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); - - fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); - } - } else { - - viewports[0] = monoViewport; - projMats[0] = monoProjMat; - - deferredTransforms[0].projection = monoProjMat; - - deferredTransforms[0].viewInverse = monoViewMat; - viewTransforms[0] = monoViewTransform; - - deferredTransforms[0].stereoSide = 0.0f; - - clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); - screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); - screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); - - fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight); - } - - auto eyePoint = viewFrustum->getPosition(); - float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft()); - - - for (int side = 0; side < numPasses; side++) { - // Render in this side's viewport - batch.setViewportTransform(viewports[side]); - batch.setStateScissorRect(viewports[side]); - - // Sync and Bind the correct DeferredTransform ubo - _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); - batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); - - glm::vec2 topLeft(-1.0f, -1.0f); - glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y); - glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w); - - // First Global directional light and ambient pass - { - bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); - - auto& program = _directionalLight; - LightLocationsPtr locations = _directionalLightLocations; - - // TODO: At some point bring back the shadows... - // Setup the global directional pass pipeline - { - if (useSkyboxCubemap) { - program = _directionalSkyboxLight; - locations = _directionalSkyboxLightLocations; - } else if (_ambientLightMode > -1) { - program = _directionalAmbientSphereLight; - locations = _directionalAmbientSphereLightLocations; - } - batch.setPipeline(program); - } - - { // Setup the global lighting - auto globalLight = _allocatedLights[_globalLights.front()]; - - if (locations->ambientSphere >= 0) { - gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); - if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { - sh = (*_skybox->getCubemap()->getIrradiance()); - } - for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); - } - } - - if (useSkyboxCubemap) { - batch.setResourceTexture(5, _skybox->getCubemap()); - } - - if (locations->lightBufferUnit >= 0) { - batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); - } + doInBatch(args, [=](gpu::Batch& batch) { - if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { - batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); - } - } - - { - batch.setModelTransform(Transform()); - batch.setProjectionTransform(glm::mat4()); - batch.setViewTransform(Transform()); - - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - } - - if (useSkyboxCubemap) { - batch.setResourceTexture(5, nullptr); - } + // Allocate the parameters buffer used by all the deferred shaders + if (!_deferredTransformBuffer[0]._buffer) { + DeferredTransform parameters; + _deferredTransformBuffer[0] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); + _deferredTransformBuffer[1] = gpu::BufferView(std::make_shared(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters)); } - auto texcoordMat = glm::mat4(); - /* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); - texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); - */ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f); - texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f); - texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); - texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + // Framebuffer copy operations cannot function as multipass stereo operations. + batch.enableStereo(false); - // enlarge the scales slightly to account for tesselation - const float SCALE_EXPANSION = 0.05f; - - - batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); - - // Splat Point lights - if (!_pointLights.empty()) { - batch.setPipeline(_pointLight); - - batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); - - for (auto lightID : _pointLights) { - auto& light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); - if (_pointLightLocations->lightBufferUnit >= 0) { - batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); - } - - float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); - // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, - // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... - if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { - Transform model; - model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); - batch.setModelTransform(model); - batch.setViewTransform(Transform()); - batch.setProjectionTransform(glm::mat4()); - - glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - - batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); - } else { - Transform model; - model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); - batch.setModelTransform(model.postScale(expandedRadius)); - batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - geometryCache->renderSphere(batch); - } - } - } + // perform deferred lighting, rendering to free fbo + auto framebufferCache = DependencyManager::get(); - // Splat spot lights - if (!_spotLights.empty()) { - batch.setPipeline(_spotLight); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); + + // binding the first framebuffer + _copyFBO = framebufferCache->getFramebuffer(); + batch.setFramebuffer(_copyFBO); - batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); + // Clearing it + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true); - for (auto lightID : _spotLights) { - auto light = _allocatedLights[lightID]; - // IN DEBUG: light->setShowContour(true); + // BInd the G-Buffer surfaces + batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture()); + batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture()); + batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture()); + batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); - batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); + // THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport) + auto monoViewport = args->_viewport; + float sMin = args->_viewport.x / (float)framebufferSize.width(); + float sWidth = args->_viewport.z / (float)framebufferSize.width(); + float tMin = args->_viewport.y / (float)framebufferSize.height(); + float tHeight = args->_viewport.w / (float)framebufferSize.height(); - auto eyeLightPos = eyePoint - light->getPosition(); - auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection()); + // The view frustum is the mono frustum base + auto viewFrustum = args->_viewFrustum; - const float TANGENT_LENGTH_SCALE = 0.666f; - glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f); + // Eval the mono projection + mat4 monoProjMat; + viewFrustum->evalProjectionMatrix(monoProjMat); - float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); - // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, - // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... - if ((eyeHalfPlaneDistance > -nearRadius) && - (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { - coneParam.w = 0.0f; - batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + // The mono view transform + Transform monoViewTransform; + viewFrustum->evalViewTransform(monoViewTransform); - Transform model; - model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); - batch.setModelTransform(model); - batch.setViewTransform(Transform()); + // THe mono view matrix coming from the mono view transform + glm::mat4 monoViewMat; + monoViewTransform.getMatrix(monoViewMat); + + // Running in stero ? + bool isStereo = args->_context->isStereo(); + int numPasses = 1; + + mat4 projMats[2]; + Transform viewTransforms[2]; + ivec4 viewports[2]; + vec4 clipQuad[2]; + vec2 screenBottomLeftCorners[2]; + vec2 screenTopRightCorners[2]; + vec4 fetchTexcoordRects[2]; + + DeferredTransform deferredTransforms[2]; + auto geometryCache = DependencyManager::get(); + + if (isStereo) { + numPasses = 2; + + mat4 eyeViews[2]; + args->_context->getStereoProjections(projMats); + args->_context->getStereoViews(eyeViews); + + float halfWidth = 0.5f * sWidth; + + for (int i = 0; i < numPasses; i++) { + // In stereo, the 2 sides are layout side by side in the mono viewport and their width is half + int sideWidth = monoViewport.z >> 1; + viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); + + deferredTransforms[i].projection = projMats[i]; + + auto sideViewMat = eyeViews[i] * monoViewMat; + viewTransforms[i].evalFromRawMatrix(sideViewMat); + deferredTransforms[i].viewInverse = sideViewMat; + + deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f); + + clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); + screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); + + fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + } + } else { + + viewports[0] = monoViewport; + projMats[0] = monoProjMat; + + deferredTransforms[0].projection = monoProjMat; + + deferredTransforms[0].viewInverse = monoViewMat; + viewTransforms[0] = monoViewTransform; + + deferredTransforms[0].stereoSide = 0.0f; + + clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); + screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); + screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); + + fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight); + } + + auto eyePoint = viewFrustum->getPosition(); + float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft()); + + + for (int side = 0; side < numPasses; side++) { + // Render in this side's viewport + batch.setViewportTransform(viewports[side]); + batch.setStateScissorRect(viewports[side]); + + // Sync and Bind the correct DeferredTransform ubo + _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); + batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); + + glm::vec2 topLeft(-1.0f, -1.0f); + glm::vec2 bottomRight(1.0f, 1.0f); + glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y); + glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w); + + // First Global directional light and ambient pass + { + bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + + auto& program = _directionalLight; + LightLocationsPtr locations = _directionalLightLocations; + + // TODO: At some point bring back the shadows... + // Setup the global directional pass pipeline + { + if (useSkyboxCubemap) { + program = _directionalSkyboxLight; + locations = _directionalSkyboxLightLocations; + } else if (_ambientLightMode > -1) { + program = _directionalAmbientSphereLight; + locations = _directionalAmbientSphereLightLocations; + } + batch.setPipeline(program); + } + + { // Setup the global lighting + auto globalLight = _allocatedLights[_globalLights.front()]; + + if (locations->ambientSphere >= 0) { + gpu::SphericalHarmonics sh = globalLight->getAmbientSphere(); + if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) { + sh = (*_skybox->getCubemap()->getIrradiance()); + } + for (int i =0; i ambientSphere + i, 1, (const float*) (&sh) + i * 4); + } + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, _skybox->getCubemap()); + } + + if (locations->lightBufferUnit >= 0) { + batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); + } + + if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) { + batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer()); + } + } + + { + batch.setModelTransform(Transform()); batch.setProjectionTransform(glm::mat4()); - + batch.setViewTransform(Transform()); + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + } + + if (useSkyboxCubemap) { + batch.setResourceTexture(5, nullptr); + } + } + + auto texcoordMat = glm::mat4(); + /* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + */ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f); + texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f); + texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); + texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + + // enlarge the scales slightly to account for tesselation + const float SCALE_EXPANSION = 0.05f; + + + batch.setProjectionTransform(projMats[side]); + batch.setViewTransform(viewTransforms[side]); + + // Splat Point lights + if (!_pointLights.empty()) { + batch.setPipeline(_pointLight); + + batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); + + for (auto lightID : _pointLights) { + auto& light = _allocatedLights[lightID]; + // IN DEBUG: light->setShowContour(true); + if (_pointLightLocations->lightBufferUnit >= 0) { + batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer()); + } + + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); + // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, + // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { + Transform model; + model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); + batch.setModelTransform(model); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(glm::mat4()); + + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); - batch.setProjectionTransform( projMats[side]); - batch.setViewTransform(viewTransforms[side]); - } else { - coneParam.w = 1.0f; - batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + batch.setProjectionTransform(projMats[side]); + batch.setViewTransform(viewTransforms[side]); + } else { + Transform model; + model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); + batch.setModelTransform(model.postScale(expandedRadius)); + batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + geometryCache->renderSphere(batch); + } + } + } + + // Splat spot lights + if (!_spotLights.empty()) { + batch.setPipeline(_spotLight); - Transform model; - model.setTranslation(light->getPosition()); - model.postRotate(light->getOrientation()); - model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius)); + batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat)); - batch.setModelTransform(model); - auto mesh = getSpotLightMesh(); + for (auto lightID : _spotLights) { + auto light = _allocatedLights[lightID]; + // IN DEBUG: light->setShowContour(true); - batch.setIndexBuffer(mesh->getIndexBuffer()); - batch.setInputBuffer(0, mesh->getVertexBuffer()); - batch.setInputFormat(mesh->getVertexFormat()); + batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer()); - auto& part = mesh->getPartBuffer().get(); + auto eyeLightPos = eyePoint - light->getPosition(); + auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection()); - batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex); + const float TANGENT_LENGTH_SCALE = 0.666f; + glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f); + + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); + // TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume, + // we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working... + if ((eyeHalfPlaneDistance > -nearRadius) && + (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) { + coneParam.w = 0.0f; + batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + + Transform model; + model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f)); + batch.setModelTransform(model); + batch.setViewTransform(Transform()); + batch.setProjectionTransform(glm::mat4()); + + glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); + + batch.setProjectionTransform( projMats[side]); + batch.setViewTransform(viewTransforms[side]); + } else { + coneParam.w = 1.0f; + batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); + + Transform model; + model.setTranslation(light->getPosition()); + model.postRotate(light->getOrientation()); + model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius)); + + batch.setModelTransform(model); + auto mesh = getSpotLightMesh(); + + batch.setIndexBuffer(mesh->getIndexBuffer()); + batch.setInputBuffer(0, mesh->getVertexBuffer()); + batch.setInputFormat(mesh->getVertexFormat()); + + auto& part = mesh->getPartBuffer().get(); + + batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex); + } } } } - } - // Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target - batch.setResourceTexture(0, nullptr); - batch.setResourceTexture(1, nullptr); - batch.setResourceTexture(2, nullptr); - batch.setResourceTexture(3, nullptr); - batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr); - - args->_context->render(batch); + // Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target + batch.setResourceTexture(0, nullptr); + batch.setResourceTexture(1, nullptr); + batch.setResourceTexture(2, nullptr); + batch.setResourceTexture(3, nullptr); + batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr); + }); // End of the Lighting pass if (!_pointLights.empty()) { @@ -687,36 +684,37 @@ void DeferredLightingEffect::render(RenderArgs* args) { void DeferredLightingEffect::copyBack(RenderArgs* args) { - gpu::Batch batch; - batch.enableStereo(false); auto framebufferCache = DependencyManager::get(); - QSize framebufferSize = framebufferCache->getFrameBufferSize(); + doInBatch(args, [=](gpu::Batch& batch) { + batch.enableStereo(false); + QSize framebufferSize = framebufferCache->getFrameBufferSize(); - // TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror. - // auto destFbo = framebufferCache->getPrimaryFramebuffer(); - auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor(); -// gpu::Vec4i vp = args->_viewport; -// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp); - batch.setFramebuffer(destFbo); - batch.setViewportTransform(args->_viewport); - batch.setProjectionTransform(glm::mat4()); - batch.setViewTransform(Transform()); - { - float sMin = args->_viewport.x / (float)framebufferSize.width(); - float sWidth = args->_viewport.z / (float)framebufferSize.width(); - float tMin = args->_viewport.y / (float)framebufferSize.height(); - float tHeight = args->_viewport.w / (float)framebufferSize.height(); - Transform model; - batch.setPipeline(_blitLightBuffer); - model.setTranslation(glm::vec3(sMin, tMin, 0.0)); - model.setScale(glm::vec3(sWidth, tHeight, 1.0)); - batch.setModelTransform(model); - } + // TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror. + // auto destFbo = framebufferCache->getPrimaryFramebuffer(); + auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor(); + // gpu::Vec4i vp = args->_viewport; + // batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp); + batch.setFramebuffer(destFbo); + batch.setViewportTransform(args->_viewport); + batch.setProjectionTransform(glm::mat4()); + batch.setViewTransform(Transform()); + { + float sMin = args->_viewport.x / (float)framebufferSize.width(); + float sWidth = args->_viewport.z / (float)framebufferSize.width(); + float tMin = args->_viewport.y / (float)framebufferSize.height(); + float tHeight = args->_viewport.w / (float)framebufferSize.height(); + Transform model; + batch.setPipeline(_blitLightBuffer); + model.setTranslation(glm::vec3(sMin, tMin, 0.0)); + model.setScale(glm::vec3(sWidth, tHeight, 1.0)); + batch.setModelTransform(model); + } - batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0)); - batch.draw(gpu::TRIANGLE_STRIP, 4); + batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0)); + batch.draw(gpu::TRIANGLE_STRIP, 4); - args->_context->render(batch); + args->_context->render(batch); + }); framebufferCache->releaseFramebuffer(_copyFBO); } diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp index cf01ccbcc9..eb05ca2a20 100644 --- a/libraries/render-utils/src/HitEffect.cpp +++ b/libraries/render-utils/src/HitEffect.cpp @@ -63,23 +63,22 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - gpu::Batch batch; + doInBatch(args, [=](gpu::Batch& batch) { - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); - batch.setPipeline(getHitEffectPipeline()); + batch.setPipeline(getHitEffectPipeline()); - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec2 bottomLeft(-1.0f, -1.0f); - glm::vec2 topRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, color); - args->_context->render((batch)); - + glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); + glm::vec2 bottomLeft(-1.0f, -1.0f); + glm::vec2 topRight(1.0f, 1.0f); + DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, color); + }); } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 137294c5b6..9beac6d386 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -32,23 +32,22 @@ using namespace render; void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { RenderArgs* args = renderContext->args; + doInBatch(args, [=](gpu::Batch& batch) { - auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); - gpu::Batch batch; - batch.enableStereo(false); - batch.setFramebuffer(nullptr); - batch.setFramebuffer(primaryFbo); + batch.enableStereo(false); + batch.setFramebuffer(nullptr); + batch.setFramebuffer(primaryFbo); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); - batch.clearFramebuffer( - gpu::Framebuffer::BUFFER_COLOR0 | - gpu::Framebuffer::BUFFER_DEPTH, - vec4(vec3(0), 1), 1.0, 0.0, true); - - args->_context->render(batch); + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_COLOR0 | + gpu::Framebuffer::BUFFER_DEPTH, + vec4(vec3(0), 1), 1.0, 0.0, true); + }); } void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { @@ -167,30 +166,28 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - gpu::Batch batch; - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - args->_batch = &batch; + doInBatch(args, [=](gpu::Batch& batch) { + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + args->_batch = &batch; - renderContext->_numDrawnOpaqueItems = inItems.size(); + renderContext->_numDrawnOpaqueItems = inItems.size(); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); - { - const float OPAQUE_ALPHA_THRESHOLD = 0.5f; - args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD; - } - - renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); - - args->_context->render((*args->_batch)); - args->_batch = nullptr; + { + const float OPAQUE_ALPHA_THRESHOLD = 0.5f; + args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD; + } + renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); + args->_batch = nullptr; + }); } void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { @@ -198,31 +195,27 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - gpu::Batch batch; - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - args->_batch = &batch; + doInBatch(args, [=](gpu::Batch& batch) { + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); + args->_batch = &batch; - renderContext->_numDrawnTransparentItems = inItems.size(); + renderContext->_numDrawnTransparentItems = inItems.size(); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); - { const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; - } - - renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems); - - args->_context->render((*args->_batch)); - args->_batch = nullptr; + renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems); + args->_batch = nullptr; + }); } gpu::PipelinePointer DrawOverlay3D::_opaquePipeline; @@ -274,8 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } // Render the items - { - gpu::Batch batch; + doInBatch(args, [=](gpu::Batch& batch) { args->_batch = &batch; args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); @@ -292,10 +284,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, args->_whiteTexture); renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems); - - args->_context->render((*args->_batch)); - args->_batch = nullptr; - args->_whiteTexture.reset(); - } + }); + args->_batch = nullptr; + args->_whiteTexture.reset(); } } diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 28b4344bf1..fc48c6207f 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -126,40 +126,38 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } // Allright, something to render let's do it - gpu::Batch batch; + doInBatch(args, [=](gpu::Batch& batch) { + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setModelTransform(Transform()); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - batch.setModelTransform(Transform()); + // bind the one gpu::Pipeline we need + batch.setPipeline(getDrawItemBoundsPipeline()); - // bind the one gpu::Pipeline we need - batch.setPipeline(getDrawItemBoundsPipeline()); + AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); + glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); - AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); - glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + const unsigned int VEC3_ADRESS_OFFSET = 3; - const unsigned int VEC3_ADRESS_OFFSET = 3; + for (int i = 0; i < nbItems; i++) { + batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); + batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); - for (int i = 0; i < nbItems; i++) { - batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); - batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); + batch.draw(gpu::LINES, 24, 0); + } - batch.draw(gpu::LINES, 24, 0); - } + batch.setPipeline(getDrawItemStatusPipeline()); + for (int i = 0; i < nbItems; i++) { + batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); + batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); + batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i)); - batch.setPipeline(getDrawItemStatusPipeline()); - for (int i = 0; i < nbItems; i++) { - batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); - batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); - batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i)); - - batch.draw(gpu::TRIANGLES, 24, 0); - } - - args->_context->render(batch); + batch.draw(gpu::TRIANGLES, 24, 0); + } + }); } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 0754d81bde..4f88b0c7af 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -235,10 +235,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext cullItems(sceneContext, renderContext, inItems, culledItems); RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - args->_batch = &theBatch; - renderItems(sceneContext, renderContext, culledItems); - args->_context->render((*args->_batch)); + doInBatch(args, [=](gpu::Batch& batch) { + args->_batch = &batch; + renderItems(sceneContext, renderContext, culledItems); + }); args->_batch = nullptr; } @@ -257,22 +257,22 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo inItems.emplace_back(id); } RenderArgs* args = renderContext->args; - gpu::Batch batch; - batch.enableSkybox(true); - batch.setViewportTransform(args->_viewport); - batch.setStateScissorRect(args->_viewport); - args->_batch = &batch; + doInBatch(args, [=](gpu::Batch& batch) { + args->_batch = &batch; + batch.enableSkybox(true); + batch.setViewportTransform(args->_viewport); + batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); - renderItems(sceneContext, renderContext, inItems); - args->_context->render((*args->_batch)); + renderItems(sceneContext, renderContext, inItems); + }); args->_batch = nullptr; } From 27688fa55bb408e589a4735871e646a4d373a03e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 23 Sep 2015 14:46:57 -0700 Subject: [PATCH 089/418] get obj models to be visible again. textures don't work --- libraries/fbx/src/OBJReader.cpp | 55 +++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 619aa901bb..ad30a38550 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -25,7 +25,6 @@ #include "OBJReader.h" #include "ModelFormatLogging.h" - QHash COMMENT_SCALE_HINTS = {{"This file uses centimeters as units", 1.0f / 100.0f}, {"This file uses millimeters as units", 1.0f / 1000.0f}}; @@ -402,10 +401,10 @@ done: FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) { - + QBuffer buffer { &model }; buffer.open(QIODevice::ReadOnly); - + FBXGeometry* geometryPtr = new FBXGeometry(); FBXGeometry& geometry = *geometryPtr; OBJTokenizer tokenizer { &buffer }; @@ -487,19 +486,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, groupMaterialName = SMART_DEFAULT_MATERIAL_NAME; } if (!groupMaterialName.isEmpty()) { - // TODO Fix this once the transision is understood - - /*// The code behind this is in transition. Some things are set directly in the FXBMeshPart... - OBJMaterial* material = &materials[groupMaterialName]; meshPart.materialID = groupMaterialName; - meshPart.diffuseTexture.filename = material->diffuseTextureFilename; - meshPart.specularTexture.filename = material->specularTextureFilename; - // ... and some things are set in the underlying material. - meshPart._material->setDiffuse(material->diffuseColor); - meshPart._material->setMetallic(glm::length(material->specularColor)); - meshPart._material->setGloss(material->shininess); - meshPart._material->setOpacity(material->opacity); - */ } foreach(OBJFace face, faceGroup) { glm::vec3 v0 = vertices[face.vertexIndices[0]]; @@ -511,7 +498,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, mesh.vertices << v1; meshPart.triangleIndices.append(mesh.vertices.count()); mesh.vertices << v2; - + glm::vec3 n0, n1, n2; if (face.normalIndices.count()) { n0 = normals[face.normalIndices[0]]; @@ -539,7 +526,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, mesh.vertices[i] *= scaleGuess; } } - + mesh.meshExtents.reset(); foreach (const glm::vec3& vertex, mesh.vertices) { mesh.meshExtents.addPoint(vertex); @@ -550,6 +537,40 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, qCDebug(modelformat) << "OBJ reader fail: " << e.what(); } + foreach (QString materialID, materials.keys()) { + OBJMaterial& objMaterial = materials[materialID]; + geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor, // glm::vec3(1.0f, 1.0f, 1.0f) + objMaterial.specularColor, // glm::vec3(1.0f) + glm::vec3(), // glm::vec3() + glm::vec2(0.f, 1.0f), // glm::vec2(0.f, 1.0f) + objMaterial.shininess, // 96.0f + objMaterial.opacity); // 1.0f + FBXMaterial& material = geometry.materials[materialID]; + material._material = std::make_shared(); + + if (!objMaterial.diffuseTextureFilename.isEmpty()) { + FBXTexture texture; + QUrl url = _url.resolved(QUrl(objMaterial.diffuseTextureFilename)); + // TODO -- something to get textures working again + } + + material._material->setEmissive(material.emissiveColor); + if (glm::all(glm::equal(material.diffuseColor, glm::vec3(0.0f)))) { + material._material->setDiffuse(material.diffuseColor); + } else { + material._material->setDiffuse(material.diffuseColor); + } + material._material->setMetallic(glm::length(material.specularColor)); + material._material->setGloss(material.shininess); + + if (material.opacity <= 0.0f) { + material._material->setOpacity(1.0f); + } else { + material._material->setOpacity(material.opacity); + } + + } + return geometryPtr; } From 276b0b71cbfc536cfc3022f10fdbb8316f3c557a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 14:52:59 -0700 Subject: [PATCH 090/418] Added tin can to master script and changed its position --- examples/toys/doll.js | 8 ---- examples/toys/masterResetEntity.js | 70 +++++++++++++++++++++++------- examples/toys/sprayPaintCan.js | 10 ++++- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/examples/toys/doll.js b/examples/toys/doll.js index 673d143d02..708d6200b1 100644 --- a/examples/toys/doll.js +++ b/examples/toys/doll.js @@ -71,11 +71,3 @@ // entity scripts always need to return a newly constructed object of our type return new Doll(); }) - -function randFloat(low, high) { - return low + Math.random() * (high - low); -} - -function randInt(low, high) { - return Math.floor(randFloat(low, high)); -} \ No newline at end of file diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b8997afe58..fda7d90908 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -23,42 +23,48 @@ function createAllToys() { }); createSprayCan({ - x: 549.12, - y: 495.55, - z: 503.77 + x: 549.8, + y: 495.6, + z: 503.94 }); createBasketBall({ - x: 548.1, - y: 497, - z: 504.6 + x: 547.73, + y: 495.5, + z: 505.47 }); createDoll({ - x: 545.9, - y: 496, - z: 506.2 + x: 546.67, + y: 495.41, + z: 505.09 }); createWand({ - x: 546.45, - y: 495.63, - z: 506.18 + x: 546.71, + y: 495.55, + z: 506.15 }); createDice(); createFlashlight({ - x: 546, - y: 495.65, - z: 506.1 + x: 545.72, + y: 495.41, + z: 505.78 }); createCat({ x: 551.107421875, y: 494.60513305664062, z: 503.1910400390625 - }) + }); + + createMagballs({ + x: 548.73, + y: 495.51, + z: 503.54 + }); //Handles toggling of all sconce lights createLightSwitches(); @@ -76,6 +82,38 @@ function deleteAllToys() { }) } +function createMagballs(position) { + + + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/tin2.fbx"; + var tinCan = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Tin Can", + position: position, + rotation: { + w: 0.93041884899139404, + x: -1.52587890625e-05, + y: 0.36647593975067139, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.16946873068809509, + y: 0.21260403096675873, + z: 0.16946862637996674 + }, + }); + + + setEntityCustomData(resetKey, tinCan, { + resetMe: true + }); + + setEntityCustomData("OmniTool", tinCan, { + script: "../toys/magBalls.js" + }); +} + function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 40a702762a..e31f7f43c6 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,7 +3,6 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); @@ -21,7 +20,16 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; + this.setRightHand = function() { + this.hand = 'RIGHT'; + } + + this.setLeftHand = function() { + this.hand = 'LEFT'; + } + this.startNearGrab = function() { + this.whichHand = this.hand; var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, From 83116fdd851cf349a74df45b9445bc44573d891d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 15:20:39 -0700 Subject: [PATCH 091/418] Fixed the code path with tseparate vertex format, still broken otherwise in the case of primitive instanced --- libraries/gpu/src/gpu/Batch.h | 21 ++++++++++++++++++++ libraries/gpu/src/gpu/Format.h | 25 +++++++++++++++++++----- libraries/gpu/src/gpu/GLBackendInput.cpp | 20 ++++++++++--------- libraries/gpu/src/gpu/Texture.cpp | 2 +- tests/gpu-test/src/main.cpp | 10 +--------- 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 9b74179967..fafc3cc8d0 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -120,7 +120,28 @@ public: void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset); void setIndexBuffer(const BufferView& buffer); // not a command, just a shortcut from a BufferView + // Indirect buffer is used by the multiDrawXXXIndirect calls + // The indirect buffer contains the command descriptions to execute multiple drawcalls in a single call void setIndirectBuffer(const BufferPointer& buffer, Offset offset = 0, Offset stride = 0); + + // multi command desctription for multiDrawIndexedIndirect + class DrawIndirectCommand { + public: + uint _count{ 0 }; + uint _instanceCount{ 0 }; + uint _firstIndex{ 0 }; + uint _baseInstance{ 0 }; + }; + + // multi command desctription for multiDrawIndexedIndirect + class DrawIndexedIndirectCommand { + public: + uint _count{ 0 }; + uint _instanceCount{ 0 }; + uint _firstIndex{ 0 }; + uint _baseVertex{ 0 }; + uint _baseInstance{ 0 }; + }; // Transform Stage // Vertex position is transformed by ModelTransform from object space to world space diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 530db084a3..ff0fd9faea 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -130,8 +130,8 @@ static const int LOCATION_COUNT[NUM_DIMENSIONS] = { 4, }; -// Count (of scalars) in an Element for a given Dimension -static const int DIMENSION_COUNT[NUM_DIMENSIONS] = { +// Count (of scalars) in an Element for a given Dimension's location +static const int SCALAR_COUNT_PER_LOCATION[NUM_DIMENSIONS] = { 1, 2, 3, @@ -141,6 +141,17 @@ static const int DIMENSION_COUNT[NUM_DIMENSIONS] = { 4, }; +// Count (of scalars) in an Element for a given Dimension +static const int SCALAR_COUNT[NUM_DIMENSIONS] = { + 1, + 2, + 3, + 4, + 4, + 9, + 16, +}; + // Semantic of an Element // Provide information on how to use the element enum Semantic { @@ -194,14 +205,18 @@ public: Semantic getSemantic() const { return (Semantic)_semantic; } Dimension getDimension() const { return (Dimension)_dimension; } - uint8 getDimensionCount() const { return DIMENSION_COUNT[(Dimension)_dimension]; } - uint8 getLocationCount() const { return LOCATION_COUNT[(Dimension)_dimension]; } + Type getType() const { return (Type)_type; } bool isNormalized() const { return (getType() >= NORMALIZED_START); } bool isInteger() const { return TYPE_IS_INTEGER[getType()]; } - uint32 getSize() const { return DIMENSION_COUNT[_dimension] * TYPE_SIZE[_type]; } + uint8 getScalarCount() const { return SCALAR_COUNT[(Dimension)_dimension]; } + uint32 getSize() const { return SCALAR_COUNT[_dimension] * TYPE_SIZE[_type]; } + + uint8 getLocationCount() const { return LOCATION_COUNT[(Dimension)_dimension]; } + uint8 getLocationScalarCount() const { return SCALAR_COUNT_PER_LOCATION[(Dimension)_dimension]; } + uint32 getLocationSize() const { return SCALAR_COUNT_PER_LOCATION[_dimension] * TYPE_SIZE[_type]; } uint16 getRaw() const { return *((uint16*) (this)); } diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index f5d456326e..f2cb914ad5 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -88,11 +88,11 @@ void GLBackend::syncInputStateCache() { // Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding // Core 43 does :) -#if (GPU_INPUT_PROFILE == GPU_CORE_41) +//#if (GPU_INPUT_PROFILE == GPU_CORE_41) #define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else +/*#else #define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif +#endif*/ void GLBackend::updateInput() { #if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) @@ -106,17 +106,18 @@ void GLBackend::updateInput() { const Stream::Attribute& attrib = (it).second; GLuint slot = attrib._slot; - GLuint count = attrib._element.getDimensionCount(); + GLuint count = attrib._element.getLocationScalarCount(); uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = _elementTypeToGLType[attrib._element.getType()]; GLuint offset = attrib._offset;; GLboolean isNormalized = attrib._element.isNormalized(); + GLenum perLocationSize = attrib._element.getLocationSize(); + for (int j = 0; j < locationCount; ++j) { newActivation.set(slot + j); - glVertexAttribFormat(slot + j, count, type, isNormalized, offset); + glVertexAttribFormat(slot + j, count, type, isNormalized, offset + j * perLocationSize); glVertexAttribDivisor(slot + j, attrib._frequency); - glVertexAttribBinding(slot + j, attrib._channel); } } @@ -225,11 +226,12 @@ void GLBackend::updateInput() { for (unsigned int i = 0; i < channel._slots.size(); i++) { const Stream::Attribute& attrib = attributes.at(channel._slots[i]); GLuint slot = attrib._slot; - GLuint count = attrib._element.getDimensionCount(); + GLuint count = attrib._element.getLocationScalarCount(); uint8_t locationCount = attrib._element.getLocationCount(); GLenum type = _elementTypeToGLType[attrib._element.getType()]; - GLenum perLocationStride = strides[bufferNum]; - GLuint stride = perLocationStride * locationCount; + // GLenum perLocationStride = strides[bufferNum]; + GLenum perLocationStride = attrib._element.getLocationSize(); + GLuint stride = strides[bufferNum]; GLuint pointer = attrib._offset + offsets[bufferNum]; GLboolean isNormalized = attrib._element.isNormalized(); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 57df7b8ec0..d358b6431d 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -629,7 +629,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< // for each face of cube texture for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { - auto numComponents = cubeTexture.accessStoredMipFace(0,face)->_format.getDimensionCount(); + auto numComponents = cubeTexture.accessStoredMipFace(0,face)->_format.getScalarCount(); auto data = cubeTexture.accessStoredMipFace(0,face)->_sysmem.readData(); if (data == nullptr) { continue; diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index 0a4a983a94..3c6da82b68 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -102,14 +102,6 @@ float getSeconds(quint64 start = 0) { return seconds; } -struct DrawElementsIndirectCommand { - uint _count{ 0 }; - uint _instanceCount{ 0 }; - uint _firstIndex{ 0 }; - uint _baseVertex{ 0 }; - uint _baseInstance{ 0 }; -}; - static const size_t TYPE_COUNT = 4; static GeometryCache::Shape SHAPE[TYPE_COUNT] = { GeometryCache::Icosahedron, @@ -300,7 +292,7 @@ public: GeometryCache::Shape shape = SHAPE[i]; GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape]; { - DrawElementsIndirectCommand indirectCommand; + gpu::Batch::DrawIndexedIndirectCommand indirectCommand; indirectCommand._count = shapeData._indexCount; indirectCommand._instanceCount = ITEM_COUNT; indirectCommand._baseInstance = i * ITEM_COUNT; From 5fd2992c284d152f687248c4e8487655e0183d1b Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 15:34:49 -0700 Subject: [PATCH 092/418] sometimes, magic happens, and clean rebuilds... --- libraries/gpu/src/gpu/GLBackendInput.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index f2cb914ad5..4877b57128 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -88,11 +88,11 @@ void GLBackend::syncInputStateCache() { // Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding // Core 43 does :) -//#if (GPU_INPUT_PROFILE == GPU_CORE_41) +#if (GPU_INPUT_PROFILE == GPU_CORE_41) #define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -/*#else +#else #define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif*/ +#endif void GLBackend::updateInput() { #if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) From 6b47373bcbd64f0722052dd3fb197b188011580a Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 23 Sep 2015 15:38:56 -0700 Subject: [PATCH 093/418] Fix for precision error in AnimPose(glm::mat4) constructor. Really the culprit is GLMHelpers extractRotation(). I have a separate unit test that demonstrates the bug. --- interface/src/avatar/SkeletonModel.cpp | 3 +-- libraries/animation/src/AnimSkeleton.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index d6fe927b0d..c248b54dc7 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -131,13 +131,12 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { headParams.localHeadYaw = head->getFinalYaw(); headParams.localHeadRoll = head->getFinalRoll(); - if (qApp->getAvatarUpdater()->isHMDMode()) { headParams.isInHMD = true; // get HMD position from sensor space into world space, and back into model space AnimPose avatarToWorld(glm::vec3(1), myAvatar->getOrientation(), myAvatar->getPosition()); - glm::mat4 worldToAvatar = (glm::mat4)avatarToWorld.inverse(); + glm::mat4 worldToAvatar = glm::inverse((glm::mat4)avatarToWorld); glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); glm::mat4 hmdMat = worldToAvatar * worldHMDMat; diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index c6bae37edd..6731756aeb 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -22,7 +22,7 @@ const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f), AnimPose::AnimPose(const glm::mat4& mat) { scale = extractScale(mat); - rot = extractRotation(mat); + rot = glm::normalize(glm::quat_cast(mat)); trans = extractTranslation(mat); } From 6bb873d327708e2541a6db75e2894e8f08213509 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 24 Sep 2015 00:43:50 +0200 Subject: [PATCH 094/418] createFlashlight.js - Close script after running Close the createFlashlight.js script after running once to prevent a flashlight from being created each time you start Interface --- examples/toys/flashlight/createFlashlight.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/toys/flashlight/createFlashlight.js b/examples/toys/flashlight/createFlashlight.js index 38907efa75..53de3bd623 100644 --- a/examples/toys/flashlight/createFlashlight.js +++ b/examples/toys/flashlight/createFlashlight.js @@ -1,5 +1,5 @@ // -// createFlashligh.js +// createFlashlight.js // examples/entityScripts // // Created by Sam Gateau on 9/9/15. @@ -46,4 +46,7 @@ function cleanup() { } -Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); + +// Close script after running once to prevent a flashlight from being created each time you start Interface +Script.stop(); From 24e2215f14970ff208cb8f0e8b9162c9c1089d41 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Sep 2015 15:47:52 -0700 Subject: [PATCH 095/418] fix mac/unix build --- libraries/gpu/src/gpu/Batch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 44bb7b11a6..0281a7390d 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -24,6 +24,10 @@ #include "Texture.h" #include "Transform.h" +// FIXME - technically according to our coding standard Context.h should be before "Framebuffer.h" but it appears +// as if Context.h is not self contained and assumes other users have included other gpu headers. +#include "Context.h" + #if defined(NSIGHT_FOUND) class ProfileRange { public: From 5176d51714730e94486a7604d7357e57f345e284 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 16:05:53 -0700 Subject: [PATCH 096/418] Merge and fix warnings --- libraries/gpu/src/gpu/GLBackendInput.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 4877b57128..0176d9ba0c 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -114,11 +114,11 @@ void GLBackend::updateInput() { GLenum perLocationSize = attrib._element.getLocationSize(); - for (int j = 0; j < locationCount; ++j) { - newActivation.set(slot + j); - glVertexAttribFormat(slot + j, count, type, isNormalized, offset + j * perLocationSize); - glVertexAttribDivisor(slot + j, attrib._frequency); - glVertexAttribBinding(slot + j, attrib._channel); + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + newActivation.set(slot + locNum); + glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); + glVertexAttribDivisor(slot + locNum, attrib._frequency); + glVertexAttribBinding(slot + locNum, attrib._channel); } } (void) CHECK_GL_ERROR(); @@ -235,10 +235,10 @@ void GLBackend::updateInput() { GLuint pointer = attrib._offset + offsets[bufferNum]; GLboolean isNormalized = attrib._element.isNormalized(); - for (int j = 0; j < locationCount; ++j) { - glVertexAttribPointer(slot + j, count, type, isNormalized, stride, - reinterpret_cast(pointer + perLocationStride * j)); - glVertexAttribDivisor(slot + j, attrib._frequency); + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + glVertexAttribPointer(slot + locNum, count, type, isNormalized, stride, + reinterpret_cast(pointer + perLocationStride * locNum)); + glVertexAttribDivisor(slot + locNum, attrib._frequency); } // TODO: Support properly the IAttrib version From a1dccc2a9236781b49a7b145bff263280b08211d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 16:13:31 -0700 Subject: [PATCH 097/418] Changed cat position --- examples/toys/cat.js | 2 +- examples/toys/masterResetEntity.js | 38 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 3aae7c6391..1f1e7cc9d4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -20,7 +20,7 @@ Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - this.distanceThreshold = 0.5; + this.distanceThreshold = 1; this.canMeow = true; this.meowBreakTime = 3000; }; diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index fda7d90908..9f8bd036c8 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -1,20 +1,28 @@ +// +// Created by Eric Levin on 9/23/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +/*global deleteAllToys, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ +//per script +/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); var resetKey = "resetMe"; -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); - createAllToys(); - - function createAllToys() { createBlocks({ x: 548.3, @@ -55,9 +63,9 @@ function createAllToys() { }); createCat({ - x: 551.107421875, - y: 494.60513305664062, - z: 503.1910400390625 + x: 551.49859619140625, + y: 495.49111938476562, + z: 502.26498413085938 }); createMagballs({ @@ -73,13 +81,13 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function(entity) { + entities.forEach(function (entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { Entities.deleteEntity(entity); } - }) + }); } function createMagballs(position) { @@ -130,9 +138,9 @@ function createCat(position) { animationSettings: animationSettings, position: position, rotation: { - w: 0.9510490894317627, - x: -1.52587890625e-05, - y: 0.30901050567626953, + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, z: -1.52587890625e-05 }, dimensions: { @@ -170,7 +178,7 @@ function createFlashlight(position) { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, shapeType: 'box', @@ -267,12 +275,12 @@ function createDice() { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, shapeType: "box", collisionsWillMove: true - } + }; var dice1 = Entities.addEntity(diceProps); diceProps.position = { From 9c44c3e4a41c2c459121d9e3d333e58234a205a2 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 16:19:34 -0700 Subject: [PATCH 098/418] Removing warnings --- libraries/gpu/src/gpu/GLBackendInput.cpp | 2 +- tests/gpu-test/src/main.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 0176d9ba0c..6a4a092c64 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -125,7 +125,7 @@ void GLBackend::updateInput() { } // Manage Activation what was and what is expected now - for (int i = 0; i < newActivation.size(); i++) { + for (size_t i = 0; i < newActivation.size(); i++) { bool newState = newActivation[i]; if (newState != _input._attributeActivation[i]) { if (newState) { diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index 3c6da82b68..97fa728c47 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -192,8 +192,6 @@ public: } void draw() { - static auto startTime = usecTimestampNow(); - // Attempting to draw before we're visible and have a valid size will // produce GL errors. if (!isVisible() || _size.width() <= 0 || _size.height() <= 0) { @@ -207,7 +205,7 @@ public: batch.setViewportTransform({ 0, 0, _size.width() * devicePixelRatio(), _size.height() * devicePixelRatio() }); batch.setProjectionTransform(_projectionMatrix); - double t = _time.elapsed() * 1e-3; + float t = _time.elapsed() * 1e-3f; glm::vec3 unitscale { 1.0f }; glm::vec3 up { 0.0f, 1.0f, 0.0f }; @@ -356,9 +354,9 @@ public: static auto startUsecs = usecTimestampNow(); float seconds = getSeconds(startUsecs); - seconds /= 4.0; + seconds /= 4.0f; int shapeIndex = ((int)seconds) % TYPE_COUNT; - bool wire = seconds - floor(seconds) > 0.5f; + bool wire = (seconds - floor(seconds) > 0.5f); batch.setModelTransform(Transform()); batch._glColor4f(0.8f, 0.25f, 0.25f, 1.0f); From d0b5d62bb76cf6bb06c5e5de4173fe5ae460fa8a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 16:21:36 -0700 Subject: [PATCH 099/418] Updated master script to make jslint happy --- examples/toys/masterResetEntity.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 9f8bd036c8..c38e8c0a26 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -360,7 +360,7 @@ function createBasketBall(position) { linearDamping: 0.0, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" @@ -397,7 +397,7 @@ function createDoll(position) { }, velocity: { x: 0, - y: -.1, + y: -0.1, z: 0 }, collisionsWillMove: true @@ -450,8 +450,10 @@ function createSprayCan(position) { } function createBlocks(position) { - var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" - var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var NUM_BLOCKS_PER_COLOR = 4; + var i, j; + var blockTypes = [{ url: "planky_blue.fbx", dimensions: { @@ -487,16 +489,13 @@ function createBlocks(position) { y: 0.05, z: 0.25 } - }, + }]; - - ]; - var NUM_BLOCKS_PER_COLOR = 4; - - for (var i = 0; i < blockTypes.length; i++) { + var modelURL, entity; + for (i = 0; i < blockTypes.length; i++) { for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { - var modelURL = baseURL + blockTypes[i].url; - var entity = Entities.addEntity({ + modelURL = baseURL + blockTypes[i].url; + entity = Entities.addEntity({ type: "Model", modelURL: modelURL, position: Vec3.sum(position, { @@ -515,7 +514,7 @@ function createBlocks(position) { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 } }); From 65a079cb53ef774d5fa53e6beb65acdf0157bc81 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 23 Sep 2015 16:48:34 -0700 Subject: [PATCH 100/418] fix mac build --- interface/src/Application.cpp | 1 + interface/src/ui/ApplicationCompositor.cpp | 1 + libraries/gpu/src/gpu/Batch.h | 9 ---- libraries/gpu/src/gpu/DoInBatch.h | 41 +++++++++++++++++++ .../input-plugins/ViveControllerManager.cpp | 1 + .../src/AmbientOcclusionEffect.cpp | 1 + .../render-utils/src/AntialiasingEffect.cpp | 1 + .../src/DeferredLightingEffect.cpp | 1 + libraries/render-utils/src/HitEffect.cpp | 1 + .../render-utils/src/RenderDeferredTask.cpp | 1 + libraries/render/src/render/DrawStatus.cpp | 1 + libraries/render/src/render/DrawTask.cpp | 2 + 12 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 libraries/gpu/src/gpu/DoInBatch.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 14d34ba8fa..76c856dfab 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 3ff13039f8..ba81e55f55 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 0281a7390d..956295fc70 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -379,13 +379,4 @@ protected: QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState); -template -void doInBatch(RenderArgs* args, F f) { - static gpu::Batch::CacheState cacheState; - gpu::Batch batch(cacheState); - f(batch); - args->_context->render(batch); - cacheState = batch.getCacheState(); -} - #endif diff --git a/libraries/gpu/src/gpu/DoInBatch.h b/libraries/gpu/src/gpu/DoInBatch.h new file mode 100644 index 0000000000..dab50bb188 --- /dev/null +++ b/libraries/gpu/src/gpu/DoInBatch.h @@ -0,0 +1,41 @@ +// +// DoInBatch.h +// interface/src/gpu +// +// Created by Brad Hefta-Gaub on 2015/09/23. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_gpu_DoInBatch_h +#define hifi_gpu_DoInBatch_h + +#include + +#include "Batch.h" +//#include "Framebuffer.h" +//#include "Pipeline.h" +//#include "Query.h" +//#include "Stream.h" +//#include "Texture.h" +//#include "Transform.h" + +// FIXME - technically according to our coding standard Context.h should be before "Framebuffer.h" but it appears +// as if Context.h is not self contained and assumes other users have included other gpu headers. +#include "Context.h" + +template +void doInBatch(RenderArgs* args, F f) { + static gpu::Batch::CacheState cacheState; + gpu::Batch batch(cacheState); + f(batch); + args->_context->render(batch); + cacheState = batch.getCacheState(); +} + + +#endif + + + diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index 3569c76d5d..6109afc7c9 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -16,6 +16,7 @@ #include "GeometryCache.h" #include #include +#include #include #include #include "NumericalConstants.h" diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 35dad58c92..1dd6ad3ae8 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "gpu/StandardShaderLib.h" #include "AmbientOcclusionEffect.h" diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 54576b7868..b9b6a4832f 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "gpu/StandardShaderLib.h" #include "AntialiasingEffect.h" diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5d079eeec1..6f43fd22e9 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "AbstractViewStateInterface.h" diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp index eb05ca2a20..c6a007e73b 100644 --- a/libraries/render-utils/src/HitEffect.cpp +++ b/libraries/render-utils/src/HitEffect.cpp @@ -26,6 +26,7 @@ #include "GeometryCache.h" #include +#include #include "hit_effect_vert.h" #include "hit_effect_frag.h" diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 9beac6d386..6169ddc077 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "FramebufferCache.h" #include "DeferredLightingEffect.h" diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index fc48c6207f..1878845e0d 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "drawItemBounds_vert.h" #include "drawItemBounds_frag.h" diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 4f88b0c7af..ed4e709e3f 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -18,6 +18,8 @@ #include #include #include +#include + using namespace render; From 381a24951e68ccff1b4ce52bdd350cd20be70dea Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 16:56:46 -0700 Subject: [PATCH 101/418] Update grab script to handle touching, better naming for non colliding grab functions --- examples/controllers/handControllerGrab.js | 266 ++++++++++++------- examples/entityScripts/changeColorOnTouch.js | 71 +++++ 2 files changed, 243 insertions(+), 94 deletions(-) create mode 100644 examples/entityScripts/changeColorOnTouch.js diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index bb806e14f1..5818815bb2 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -8,11 +8,10 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ Script.include("../libraries/utils.js"); - ///////////////////////////////////////////////////////////////// // // these tune time-averaging and "on" value for analog trigger @@ -110,40 +109,40 @@ function controller(hand, triggerAction) { this.state = 0; this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value - - this.update = function() { + var _this = this; + this.update = function () { switch (this.state) { - case STATE_SEARCHING: - this.search(); - break; - case STATE_DISTANCE_HOLDING: - this.distanceHolding(); - break; - case STATE_CONTINUE_DISTANCE_HOLDING: - this.continueDistanceHolding(); - break; - case STATE_NEAR_GRABBING: - this.nearGrabbing(); - break; - case STATE_CONTINUE_NEAR_GRABBING: - this.continueNearGrabbing(); - break; - case STATE_NEAR_GRABBING_NON_COLLIDING: - this.nearGrabbingNonColliding(); - break; - case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: - this.continueNearGrabbingNonColliding(); - break; - case STATE_RELEASE: - this.release(); - break; + case STATE_SEARCHING: + this.search(); + this.touchTest(); + break; + case STATE_DISTANCE_HOLDING: + this.distanceHolding(); + break; + case STATE_CONTINUE_DISTANCE_HOLDING: + this.continueDistanceHolding(); + break; + case STATE_NEAR_GRABBING: + this.nearGrabbing(); + break; + case STATE_CONTINUE_NEAR_GRABBING: + this.continueNearGrabbing(); + break; + case STATE_NEAR_GRABBING_NON_COLLIDING: + this.nearGrabbingNonColliding(); + break; + case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: + this.continueNearGrabbingNonColliding(); + break; + case STATE_RELEASE: + this.release(); + break; } - } - - - this.lineOn = function(closePoint, farPoint, color) { + }; + _this.pointerIDs = []; + this.lineOn = function (closePoint, farPoint, color) { // draw a line - if (this.pointer == null) { + if (this.pointer === null) { this.pointer = Entities.addEntity({ type: "Line", name: "pointer", @@ -154,6 +153,7 @@ function controller(hand, triggerAction) { color: color, lifetime: LIFETIME }); + _this.pointerIDs.push(this.pointer); } else { Entities.editEntity(this.pointer, { position: closePoint, @@ -162,33 +162,40 @@ function controller(hand, triggerAction) { lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME }); } - } + + }; - this.lineOff = function() { - if (this.pointer != null) { + this.lineOff = function () { + if (this.pointer !== null) { Entities.deleteEntity(this.pointer); } + var index = _this.pointerIDs.indexOf(this.pointer); + if (index > -1) { + _this.pointerIDs.splice(index, 1); + } this.pointer = null; - } + }; - this.triggerSmoothedSqueezed = function() { + this.triggerSmoothedSqueezed = function () { var triggerValue = Controller.getActionValue(this.triggerAction); // smooth out trigger value this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + (triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO)); return this.triggerValue > TRIGGER_ON_VALUE; - } + }; - this.triggerSqueezed = function() { + this.triggerSqueezed = function () { var triggerValue = Controller.getActionValue(this.triggerAction); return triggerValue > TRIGGER_ON_VALUE; - } + }; + + + this.search = function () { - this.search = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -220,10 +227,10 @@ function controller(hand, triggerAction) { // forward ray test failed, try sphere test. var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var minDistance = GRAB_RADIUS; - var grabbedEntity = null; - for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); - var distance = Vec3.distance(props.position, handPosition); + var i, props, distance; + for (i = 0; i < nearbyEntities.length; i++) { + props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); + distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; @@ -238,10 +245,11 @@ function controller(hand, triggerAction) { this.state = STATE_NEAR_GRABBING_NON_COLLIDING; } } - } + + }; - this.distanceHolding = function() { + this.distanceHolding = function () { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); @@ -259,25 +267,26 @@ function controller(hand, triggerAction) { targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME }); - if (this.actionID == NULL_ACTION_ID) { + if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } - if (this.actionID != null) { + if (this.actionID !== null) { this.state = STATE_CONTINUE_DISTANCE_HOLDING; this.activateEntity(this.grabbedEntity); - Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); - if (this.hand === RIGHT_HAND) { Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); } else { Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); } } - } + Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); - this.continueDistanceHolding = function() { + }; + + + this.continueDistanceHolding = function () { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -323,10 +332,10 @@ function controller(hand, triggerAction) { targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME }); - } + }; - this.nearGrabbing = function() { + this.nearGrabbing = function () { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -344,51 +353,34 @@ function controller(hand, triggerAction) { var objectRotation = grabbedProperties.rotation; var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); - currentObjectPosition = grabbedProperties.position; + var currentObjectPosition = grabbedProperties.position; var offset = Vec3.subtract(currentObjectPosition, handPosition); var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand == RIGHT_HAND ? "right" : "left", + hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: offsetPosition, relativeRotation: offsetRotation }); - if (this.actionID == NULL_ACTION_ID) { + if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { this.state = STATE_CONTINUE_NEAR_GRABBING; - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); if (this.hand === RIGHT_HAND) { Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); } else { Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); } + Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); + } this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm); this.currentObjectTime = Date.now(); - } + }; - this.nearGrabbingNonColliding = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding") - this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; - } - - this.continueNearGrabNonColliding = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabNonColliding"); - } - - - this.continueNearGrabbing = function() { + this.continueNearGrabbing = function () { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -405,10 +397,96 @@ function controller(hand, triggerAction) { this.currentHandControllerPosition = handControllerPosition; this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - } + }; + this.nearGrabbingNonColliding = function () { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding"); + this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; + }; - this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) { + this.continueNearGrabbingNonColliding = function () { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); + }; + + _this.allTouchedIDs = {}; + this.touchTest = function () { + //print('touch test'); + var maxDistance = 0.05; + var leftHandPosition = MyAvatar.getLeftPalmPosition(); + var rightHandPosition = MyAvatar.getRightPalmPosition(); + var leftEntities = Entities.findEntities(leftHandPosition, maxDistance); + var rightEntities = Entities.findEntities(rightHandPosition, maxDistance); + var ids = []; + if (leftEntities.length !== 0) { + leftEntities.forEach(function (entity) { + ids.push(entity); + }); + + } + if (rightEntities.length !== 0) { + rightEntities.forEach(function (entity) { + ids.push(entity); + }); + } + + ids.forEach(function (id) { + + var props = Entities.getEntityProperties(id, ["boundingBox", "name"]); + if (props.name === 'pointer') { + return; + } else { + var entityMinPoint = props.boundingBox.brn; + var entityMaxPoint = props.boundingBox.tfl; + var leftIsTouching = pointInExtents(leftHandPosition, entityMinPoint, entityMaxPoint); + var rightIsTouching = pointInExtents(rightHandPosition, entityMinPoint, entityMaxPoint); + + if ((leftIsTouching || rightIsTouching) && _this.allTouchedIDs[id] === undefined) { + // we haven't been touched before, but either right or left is touching us now + _this.allTouchedIDs[id] = true; + _this.startTouch(id); + } else if ((leftIsTouching || rightIsTouching) && _this.allTouchedIDs[id] === true) { + // we have been touched before and are still being touched + // continue touch + _this.continueTouch(id); + } else if (_this.allTouchedIDs[id] === true) { + delete _this.allTouchedIDs[id]; + _this.stopTouch(id); + + } else { + //we are in another state + return; + } + } + + }); + + }; + + this.startTouch = function (entityID) { + // print('START TOUCH' + entityID); + Entities.callEntityMethod(entityID, "startTouch"); + }; + + this.continueTouch = function (entityID) { + // print('CONTINUE TOUCH' + entityID); + Entities.callEntityMethod(entityID, "continueTouch"); + }; + + this.stopTouch = function (entityID) { + // print('STOP TOUCH' + entityID); + Entities.callEntityMethod(entityID, "stopTouch"); + + }; + + this.computeReleaseVelocity = function (deltaPosition, deltaTime, useMultiplier) { if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) { var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime); // don't update grabbedVelocity if the trigger is off. the smoothing of the trigger @@ -423,13 +501,13 @@ function controller(hand, triggerAction) { this.grabbedVelocity = Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER); } } - } + }; - this.release = function() { + this.release = function () { this.lineOff(); - if (this.grabbedEntity != null && this.actionID != null) { + if (this.grabbedEntity !== null && this.actionID !== null) { Entities.deleteAction(this.grabbedEntity, this.actionID); Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); } @@ -445,28 +523,28 @@ function controller(hand, triggerAction) { this.grabbedEntity = null; this.actionID = null; this.state = STATE_SEARCHING; - } + }; - this.cleanup = function() { - release(); - } + this.cleanup = function () { + this.release(); + }; - this.activateEntity = function(entity) { + this.activateEntity = function () { var data = { activated: true, avatarId: MyAvatar.sessionUUID }; setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } + }; - this.deactivateEntity = function(entity) { + this.deactivateEntity = function () { var data = { activated: false, avatarId: null }; setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } + }; } @@ -487,4 +565,4 @@ function cleanup() { Script.scriptEnding.connect(cleanup); -Script.update.connect(update) \ No newline at end of file +Script.update.connect(update); \ No newline at end of file diff --git a/examples/entityScripts/changeColorOnTouch.js b/examples/entityScripts/changeColorOnTouch.js new file mode 100644 index 0000000000..b3082fa9d5 --- /dev/null +++ b/examples/entityScripts/changeColorOnTouch.js @@ -0,0 +1,71 @@ +// +// changeColorOnTouch.js +// examples/entityScripts +// +// Created by Brad Hefta-Gaub on 11/1/14. +// Additions by James B. Pollack @imgntn on 9/23/2015 +// Copyright 2014 High Fidelity, Inc. +// +// ATTENTION: Requires you to run handControllerGrab.js +// This is an example of an entity script which when assigned to a non-model entity like a box or sphere, will +// change the color of the entity when you touch it. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function () { + ChangeColorOnTouch = function () { + this.oldColor = {}; + this.oldColorKnown = false; + }; + + ChangeColorOnTouch.prototype = { + + storeOldColor: function (entityID) { + var oldProperties = Entities.getEntityProperties(entityID); + this.oldColor = oldProperties.color; + this.oldColorKnown = true; + print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue); + }, + + preload: function (entityID) { + print("preload"); + this.entityID = entityID; + this.storeOldColor(entityID); + }, + + startTouch: function () { + print("startTouch"); + if (!this.oldColorKnown) { + this.storeOldColor(this.entityID); + } + Entities.editEntity(this.entityID, { + color: { + red: 0, + green: 255, + blue: 255 + } + }); + }, + + continueTouch: function () { + //unused here + return; + }, + + stopTouch: function () { + print("stopTouch"); + if (this.oldColorKnown) { + print("leave restoring old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue); + Entities.editEntity(this.entityID, { + color: this.oldColor + }); + } + } + + + }; + + return new ChangeColorOnTouch(); +}) \ No newline at end of file From a2c7b3bcc9ff863ad8f361c6cdeb537cbd13dec0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 23 Sep 2015 17:00:07 -0700 Subject: [PATCH 102/418] Orient particles to face camera but not roll with it --- .../src/RenderableParticleEffectEntityItem.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 68567372e2..005252672d 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -211,9 +211,12 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { _vertices.clear(); // build vertices from particle positions and radiuses - const glm::vec3 up = frustum->getUp(); - const glm::vec3 right = frustum->getRight(); + glm::vec3 frustumPosition = frustum->getPosition(); for (auto&& particle : particleDetails) { + glm::vec3 particleDirection = particle.position - frustumPosition; + glm::vec3 right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), particleDirection)); + glm::vec3 up = glm::normalize(glm::cross(right, particleDirection)); + glm::vec3 upOffset = up * particle.radius; glm::vec3 rightOffset = right * particle.radius; // generate corners of quad aligned to face the camera. From 62c1e4012769a0ee90f9e831a1c751e4f92dbc45 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Sep 2015 17:15:29 -0700 Subject: [PATCH 103/418] CR repairs --- libraries/gpu/src/gpu/DoInBatch.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/libraries/gpu/src/gpu/DoInBatch.h b/libraries/gpu/src/gpu/DoInBatch.h index dab50bb188..93b7dddbc6 100644 --- a/libraries/gpu/src/gpu/DoInBatch.h +++ b/libraries/gpu/src/gpu/DoInBatch.h @@ -14,17 +14,10 @@ #include #include "Batch.h" -//#include "Framebuffer.h" -//#include "Pipeline.h" -//#include "Query.h" -//#include "Stream.h" -//#include "Texture.h" -//#include "Transform.h" - -// FIXME - technically according to our coding standard Context.h should be before "Framebuffer.h" but it appears -// as if Context.h is not self contained and assumes other users have included other gpu headers. #include "Context.h" +// FIXME -- ideally we'd like this to be in Batch.h, but gcc was not happy with the first cut at that, +// it was complaining with error: member access into incomplete type 'element_type' (aka 'gpu::Context') template void doInBatch(RenderArgs* args, F f) { static gpu::Batch::CacheState cacheState; From 153a30de0dfa42f2b237a81484af35c3a50df1fd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 17:24:56 -0700 Subject: [PATCH 104/418] flip --- examples/toys/lightSwitchGarage.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 090e1260bf..97cd0a6ac3 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -30,7 +30,7 @@ LightSwitchGarage.prototype = { - clickReleaseOnEntity: function(entityId, mouseEvent) { + clickReleaseOnEntity: function(entityID, mouseEvent) { if (!mouseEvent.isLeftButton) { return; } @@ -52,6 +52,18 @@ this.createLights(); } + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = Quat.axis(rotation); + var angle = Quat.angle(rotation); + + angle += 180; + rotation = Quat.angleAxis(angle, axis); + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + Audio.playSound(this.switchSound, { volume: 0.5, position: this.position From 81c175eabf524f44011aa56ba1f4599ef23a113d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 17:34:37 -0700 Subject: [PATCH 105/418] toggle light switch --- examples/toys/lightSwitchGarage.js | 7 +++---- examples/toys/lightSwitchHall.js | 17 ++++++++++++++++- examples/toys/masterResetEntity.js | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 97cd0a6ac3..a68a09cf7d 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -54,11 +54,10 @@ // flip model to give illusion of light switch being flicked var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = Quat.axis(rotation); - var angle = Quat.angle(rotation); + var axis = {x: 0, y: 1, z: 0}; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); - angle += 180; - rotation = Quat.angleAxis(angle, axis); Entities.editEntity(this.entityID, { rotation: rotation diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 356dee928c..6bc1eeab83 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -52,6 +52,21 @@ this.createLights(); } + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + Audio.playSound(this.switchSound, { volume: 0.5, position: this.position @@ -104,7 +119,7 @@ var sconceLight2 = Entities.addEntity({ type: "Light", position: { - x: 540.1 , + x: 540.1, y: 496.24, z: 505.57 }, diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c38e8c0a26..c94f1bde9b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -191,7 +191,7 @@ function createFlashlight(position) { } function createLightSwitches() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); var lightSwitchHall = Entities.addEntity({ From 9a0e5b987035aa872f53074f6df36defaed61baa Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Sep 2015 17:37:48 -0700 Subject: [PATCH 106/418] address Sam's concerns --- interface/src/Application.cpp | 8 ++--- interface/src/ui/ApplicationCompositor.cpp | 5 ++- libraries/gpu/src/gpu/Batch.h | 5 +-- libraries/gpu/src/gpu/Context.h | 9 +++++ libraries/gpu/src/gpu/DoInBatch.h | 34 ------------------- .../input-plugins/ViveControllerManager.cpp | 3 +- .../src/AmbientOcclusionEffect.cpp | 3 +- .../render-utils/src/AntialiasingEffect.cpp | 3 +- .../src/DeferredLightingEffect.cpp | 7 ++-- libraries/render-utils/src/HitEffect.cpp | 3 +- .../render-utils/src/RenderDeferredTask.cpp | 9 +++-- libraries/render/src/render/DrawStatus.cpp | 3 +- libraries/render/src/render/DrawTask.cpp | 5 ++- 13 files changed, 29 insertions(+), 68 deletions(-) delete mode 100644 libraries/gpu/src/gpu/DoInBatch.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 76c856dfab..8e28d2cbcb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -69,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -1087,12 +1086,11 @@ void Application::paintGL() { auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w); auto selfieFbo = DependencyManager::get()->getSelfieFramebuffer(); - doInBatch(&renderArgs, [=](gpu::Batch& batch) { + doInBatch(renderArgs._context, [=](gpu::Batch& batch) { batch.setFramebuffer(selfieFbo); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest); batch.setFramebuffer(nullptr); - renderArgs._context->render(batch); }); } } @@ -1217,7 +1215,7 @@ void Application::paintGL() { } displaySide(&renderArgs, _myCamera); renderArgs._context->enableStereo(false); - doInBatch(&renderArgs, [](gpu::Batch& batch) { + doInBatch(renderArgs._context, [](gpu::Batch& batch) { batch.setFramebuffer(nullptr); }); } @@ -1281,7 +1279,7 @@ void Application::paintGL() { // Reset the gpu::Context Stages // Back to the default framebuffer; - doInBatch(&renderArgs, [=](gpu::Batch& batch) { + doInBatch(renderArgs._context, [=](gpu::Batch& batch) { batch.resetStages(); }); } diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index ba81e55f55..ec93137d3a 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -208,7 +207,7 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { updateTooltips(); //Handle fading and deactivation/activation of UI - doInBatch(renderArgs, [=](gpu::Batch& batch) { + doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { auto geometryCache = DependencyManager::get(); @@ -279,7 +278,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int auto geometryCache = DependencyManager::get(); - doInBatch(renderArgs, [=](gpu::Batch& batch) { + doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { geometryCache->useSimpleDrawPipeline(batch); batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 956295fc70..6743b8adc5 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -11,7 +11,7 @@ #ifndef hifi_gpu_Batch_h #define hifi_gpu_Batch_h -#include +//#include #include #include @@ -24,9 +24,6 @@ #include "Texture.h" #include "Transform.h" -// FIXME - technically according to our coding standard Context.h should be before "Framebuffer.h" but it appears -// as if Context.h is not self contained and assumes other users have included other gpu headers. -#include "Context.h" #if defined(NSIGHT_FOUND) class ProfileRange { diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index e0d6c08af6..286decfad4 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -217,4 +217,13 @@ typedef std::shared_ptr ContextPointer; }; +template +void doInBatch(std::shared_ptr context, F f) { + static gpu::Batch::CacheState cacheState; + gpu::Batch batch(cacheState); + f(batch); + context->render(batch); + cacheState = batch.getCacheState(); +} + #endif diff --git a/libraries/gpu/src/gpu/DoInBatch.h b/libraries/gpu/src/gpu/DoInBatch.h deleted file mode 100644 index 93b7dddbc6..0000000000 --- a/libraries/gpu/src/gpu/DoInBatch.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// DoInBatch.h -// interface/src/gpu -// -// Created by Brad Hefta-Gaub on 2015/09/23. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#ifndef hifi_gpu_DoInBatch_h -#define hifi_gpu_DoInBatch_h - -#include - -#include "Batch.h" -#include "Context.h" - -// FIXME -- ideally we'd like this to be in Batch.h, but gcc was not happy with the first cut at that, -// it was complaining with error: member access into incomplete type 'element_type' (aka 'gpu::Context') -template -void doInBatch(RenderArgs* args, F f) { - static gpu::Batch::CacheState cacheState; - gpu::Batch batch(cacheState); - f(batch); - args->_context->render(batch); - cacheState = batch.getCacheState(); -} - - -#endif - - - diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index 6109afc7c9..3d6f2e1656 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -16,7 +16,6 @@ #include "GeometryCache.h" #include #include -#include #include #include #include "NumericalConstants.h" @@ -174,7 +173,7 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()]; UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()]; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { auto geometryCache = DependencyManager::get(); geometryCache->useSimpleDrawPipeline(batch); DependencyManager::get()->bindSimpleProgram(batch, true); diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 1dd6ad3ae8..73c316648b 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include "gpu/StandardShaderLib.h" #include "AmbientOcclusionEffect.h" @@ -180,7 +179,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { auto framebufferCache = DependencyManager::get(); QSize framebufferSize = framebufferCache->getFrameBufferSize(); float fbWidth = framebufferSize.width(); diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index b9b6a4832f..9af3f90a4e 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include "gpu/StandardShaderLib.h" #include "AntialiasingEffect.h" @@ -102,7 +101,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re } RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); auto framebufferCache = DependencyManager::get(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6f43fd22e9..5ace0d4e13 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include "AbstractViewStateInterface.h" @@ -341,7 +340,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu } void DeferredLightingEffect::prepare(RenderArgs* args) { - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); batch.setStateScissorRect(args->_viewport); @@ -358,7 +357,7 @@ void DeferredLightingEffect::prepare(RenderArgs* args) { gpu::FramebufferPointer _copyFBO; void DeferredLightingEffect::render(RenderArgs* args) { - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { // Allocate the parameters buffer used by all the deferred shaders if (!_deferredTransformBuffer[0]._buffer) { @@ -686,7 +685,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { void DeferredLightingEffect::copyBack(RenderArgs* args) { auto framebufferCache = DependencyManager::get(); - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); QSize framebufferSize = framebufferCache->getFrameBufferSize(); diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp index c6a007e73b..b3915aa072 100644 --- a/libraries/render-utils/src/HitEffect.cpp +++ b/libraries/render-utils/src/HitEffect.cpp @@ -26,7 +26,6 @@ #include "GeometryCache.h" #include -#include #include "hit_effect_vert.h" #include "hit_effect_frag.h" @@ -64,7 +63,7 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 6169ddc077..35ac2e4af2 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include "FramebufferCache.h" #include "DeferredLightingEffect.h" @@ -33,7 +32,7 @@ using namespace render; void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); @@ -167,7 +166,7 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; @@ -196,7 +195,7 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; @@ -268,7 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } // Render the items - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 1878845e0d..66067f3ff2 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -19,7 +19,6 @@ #include #include -#include #include "drawItemBounds_vert.h" #include "drawItemBounds_frag.h" @@ -127,7 +126,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } // Allright, something to render let's do it - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index ed4e709e3f..644b9b0adf 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -18,7 +18,6 @@ #include #include #include -#include using namespace render; @@ -237,7 +236,7 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext cullItems(sceneContext, renderContext, inItems, culledItems); RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; renderItems(sceneContext, renderContext, culledItems); }); @@ -259,7 +258,7 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo inItems.emplace_back(id); } RenderArgs* args = renderContext->args; - doInBatch(args, [=](gpu::Batch& batch) { + doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; batch.enableSkybox(true); batch.setViewportTransform(args->_viewport); From 432dc2055f319705134ea7e9aa8213a52228c4c7 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Sep 2015 17:38:59 -0700 Subject: [PATCH 107/418] gak --- libraries/gpu/src/gpu/Batch.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 6743b8adc5..4da79f9bfe 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -11,8 +11,6 @@ #ifndef hifi_gpu_Batch_h #define hifi_gpu_Batch_h -//#include - #include #include #include From 82f178a3532a878c1a4cf74b1d4f31f08ba7dab1 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 17:43:08 -0700 Subject: [PATCH 108/418] tweaks --- examples/toys/doll/doll.js | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 1417798799..835685e6bb 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -38,24 +38,14 @@ rightHand: false, handIsSet: false, setLeftHand: function () { - if (this.handIsSet === false) { - this.leftHand = true; - this.rightHand = false; - this.setHand = 'left'; - this.handIsSet = true; - } else { + this.currentHand = 'left' - } + }, setRightHand: function () { - if (this.handIsSet === false) { - this.rightHand = true; - this.leftHand = false; - this.setHand = 'right'; - this.handIsSet = true; - } else { + this.currentHand = 'right' - } + }, startNearGrab: function () { if (this.isGrabbed === false) { @@ -70,18 +60,17 @@ volume: 0.1 }); this.isGrabbed = true; + this.initialHand = this.hand; + print('INITIAL HAND:::' +this.initialHand) } }, continueNearGrab: function () { - if (this.setHand === this.currentHand) { + print('CONTINUING GRAB IN HAND') var position = Entities.getEntityProperties(this.entityID, "position").position; this.audioInjector.options.position = position; - }else{ - print('NOT SAME HAND GRABBING') - } - + }, releaseGrab: function () { @@ -92,12 +81,7 @@ }); this.isGrabbed = false; } - if(this.setHand===this.currentHand){ - print('SAME HAND LET GO') - } - else{ - print('DIFFERENT HAND KEEP HOLDING') - } + }, From 37ecd180545dcec7b6812af728c270518eceaaf7 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 17:44:28 -0700 Subject: [PATCH 109/418] put distant grab inside of conditional --- examples/controllers/handControllerGrab.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 5818815bb2..c6c1befda7 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -279,8 +279,9 @@ function controller(hand, triggerAction) { } else { Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); } + Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); } - Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); + }; From b8e630a7a781c87bedd7e72830d7141b449d732e Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 17:46:10 -0700 Subject: [PATCH 110/418] Less Warnigns --- tests/gpu-test/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index 97fa728c47..e4853bf596 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -210,7 +210,7 @@ public: glm::vec3 up { 0.0f, 1.0f, 0.0f }; float distance = 3.0f; - glm::vec3 camera_position{ distance * sinf(t), 0.0f, distance * cos(t) }; + glm::vec3 camera_position{ distance * sinf(t), 0.0f, distance * cosf(t) }; static const vec3 camera_focus(0); static const vec3 camera_up(0, 1, 0); @@ -356,7 +356,7 @@ public: seconds /= 4.0f; int shapeIndex = ((int)seconds) % TYPE_COUNT; - bool wire = (seconds - floor(seconds) > 0.5f); + bool wire = (seconds - floorf(seconds) > 0.5f); batch.setModelTransform(Transform()); batch._glColor4f(0.8f, 0.25f, 0.25f, 1.0f); From 7d8f3661ad9d3af0e02d9b7a409d0515137d0071 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 23 Sep 2015 17:49:03 -0700 Subject: [PATCH 111/418] coding standard --- tests/gpu-test/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index e4853bf596..80c2dbf8e9 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -157,7 +157,7 @@ public: show(); makeCurrent(); - QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); + QOpenGLDebugLogger* logger = new QOpenGLDebugLogger(this); logger->initialize(); // initializes in the current context, i.e. ctx connect(logger, &QOpenGLDebugLogger::messageLogged, [](const QOpenGLDebugMessage& message){ qDebug() << message; From 7efd15c3a214e8b39a8864a290ff21b2898ef978 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 23 Sep 2015 18:01:18 -0700 Subject: [PATCH 112/418] Update doll to stop screaming when released, use only one hand a a time, spatialize audio position --- examples/toys/doll/createDoll.js | 11 ++++++++ examples/toys/doll/doll.js | 45 +++++++++++++------------------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/examples/toys/doll/createDoll.js b/examples/toys/doll/createDoll.js index fef55bd95b..8cb93a15df 100644 --- a/examples/toys/doll/createDoll.js +++ b/examples/toys/doll/createDoll.js @@ -1,3 +1,14 @@ +// createDoll.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn 9/23/2015 +// Copyright 2015 High Fidelity, Inc. +// +// ATTENTION: requires that you run handController.js +// Creates a doll entity in front of you. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ function createDoll() { diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 835685e6bb..12a41d5e98 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -4,8 +4,8 @@ // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This entity script breathes movement and sound- one might even say life- into a doll. -// This entity script plays an animation and a sound while you hold +// ATTENTION: requires that you run handController.js +// This entity script plays an animation and a sound while you hold it. // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -14,11 +14,9 @@ Script.include("../../utilities.js"); Script.include("../../libraries/utils.js"); - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + // this is the "constructor" for the entity as a JS object we don't do much here var Doll = function () { this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; - }; Doll.prototype = { @@ -34,19 +32,14 @@ }), audioInjector: null, isGrabbed: false, - leftHand: false, - rightHand: false, - handIsSet: false, setLeftHand: function () { - - this.currentHand = 'left' - + this.hand = 'left'; }, + setRightHand: function () { - - this.currentHand = 'right' - + this.hand = 'right'; }, + startNearGrab: function () { if (this.isGrabbed === false) { Entities.editEntity(this.entityID, { @@ -61,38 +54,36 @@ }); this.isGrabbed = true; this.initialHand = this.hand; - print('INITIAL HAND:::' +this.initialHand) + } - }, + continueNearGrab: function () { - - print('CONTINUING GRAB IN HAND') - var position = Entities.getEntityProperties(this.entityID, "position").position; - this.audioInjector.options.position = position; - + var position = Entities.getEntityProperties(this.entityID, "position").position; + var audioOptions = { + position: position + }; + this.audioInjector.options = audioOptions; }, releaseGrab: function () { - if (this.isGrabbed === true) { + if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); + Entities.editEntity(this.entityID, { + animationSettings: this.stopAnimationSetting + }); Entities.editEntity(this.entityID, { animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); this.isGrabbed = false; } - - }, - // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: // * remembering our entityID, so we can access it in cases where we're called without an entityID - // * connecting to the update signal so we can check our grabbed state preload: function (entityID) { this.entityID = entityID; - }, }; From 3d44fdfdf5fc56bd563129d46437b91587ed36df Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 23 Sep 2015 21:18:23 -0700 Subject: [PATCH 113/418] Fix warnings --- libraries/entities/src/ParticleEffectEntityItem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 9958c0ac1e..8c45c860fa 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -704,7 +704,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { if (_azimuthFinish >= _azimuthStart) { azimuth = _azimuthStart + (_azimuthFinish - _azimuthStart) * randFloat(); } else { - azimuth = _azimuthStart + (2.0 * PI + _azimuthFinish - _azimuthStart) * randFloat(); + azimuth = _azimuthStart + (2.0f * PI + _azimuthFinish - _azimuthStart) * randFloat(); } glm::vec3 emitDirection; @@ -721,13 +721,13 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { if (_emitRadiusStart < 1.0f) { float emitRadiusStart = glm::max(_emitRadiusStart, EPSILON); // Avoid math complications at center float randRadius = emitRadiusStart + (1.0f - emitRadiusStart) * randFloat(); - radiusScale = 1.0f - std::pow(1.0f - randRadius, 3); + radiusScale = 1.0f - std::pow(1.0f - randRadius, 3.0f); } glm::vec3 radiuses = radiusScale * 0.5f * _emitDimensions; - float x = radiuses.x * cos(elevation) * cos(azimuth); - float y = radiuses.y * cos(elevation) * sin(azimuth); - float z = radiuses.z * sin(elevation); + float x = radiuses.x * glm::cos(elevation) * glm::cos(azimuth); + float y = radiuses.y * glm::cos(elevation) * glm::sin(azimuth); + float z = radiuses.z * glm::sin(elevation); glm::vec3 emitPosition = glm::vec3(x, y, z); emitDirection = glm::normalize(glm::vec3( x / (radiuses.x * radiuses.x), From 5e82b9c43371ab129c9a161943963bc32009c5b4 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 24 Sep 2015 08:26:56 -0700 Subject: [PATCH 114/418] more warning fixes --- interface/src/ui/ApplicationOverlay.cpp | 2 -- libraries/animation/src/Rig.cpp | 6 ++++-- libraries/audio/src/AudioInjector.cpp | 1 + libraries/render-utils/src/AnimDebugDraw.cpp | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 120f97971c..7254295c2f 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -94,8 +94,6 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { renderArgs->_context->render(batch); - qDebug() << "ApplicationOverlay::renderOverlay() batch:" << batch.getCacheState(); - renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch CHECK_GL_ERROR(); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 216f091f93..f1e81df64e 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -992,11 +992,13 @@ static AnimPose avatarToBonePose(AnimPose pose, AnimSkeleton::ConstPointer skele return rootPose * rotY180 * pose; } +#ifdef DEBUG_RENDERING static AnimPose boneToAvatarPose(AnimPose pose, AnimSkeleton::ConstPointer skeleton) { AnimPose rootPose = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Hips")); AnimPose rotY180(glm::vec3(1), glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)), glm::vec3(0)); return (rootPose * rotY180).inverse() * pose; } +#endif static void computeHeadNeckAnimVars(AnimSkeleton::ConstPointer skeleton, const AnimPose& avatarHMDPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut, @@ -1046,7 +1048,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { computeHeadNeckAnimVars(_animSkeleton, avatarHMDPose, headPos, headRot, neckPos, neckRot); // debug rendering - /* +#ifdef DEBUG_RENDERING const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); const glm::vec4 green(0.0f, 1.0f, 0.0f, 1.0f); @@ -1059,7 +1061,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { AnimPose neckPose(glm::vec3(1), neckRot, neckPos); neckPose = boneToAvatarPose(neckPose, _animSkeleton); DebugDraw::getInstance().addMyAvatarMarker("neckTarget", neckPose.rot, neckPose.trans, green); - */ +#endif _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index a3577e6c58..334c44c4c5 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -330,6 +330,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol reinterpret_cast(resampled.data()), nInputFrames); + Q_UNUSED(nOutputFrames); return playSoundAndDelete(resampled, options, NULL); } diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 2db9094bcb..73f7b43ddb 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -488,6 +488,7 @@ void AnimDebugDraw::update() { glm::quat rot = std::get<0>(iter.second); glm::vec3 pos = std::get<1>(iter.second); glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. + Q_UNUSED(color); const float radius = POSE_RADIUS; addBone(AnimPose::identity, AnimPose(glm::vec3(1), rot, pos), radius, v); } @@ -497,6 +498,7 @@ void AnimDebugDraw::update() { glm::quat rot = std::get<0>(iter.second); glm::vec3 pos = std::get<1>(iter.second); glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. + Q_UNUSED(color); const float radius = POSE_RADIUS; addBone(myAvatarPose, AnimPose(glm::vec3(1), rot, pos), radius, v); } From 776acf2182c9b99710aaf60dc5f3438b99eff1e0 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 24 Sep 2015 09:07:43 -0700 Subject: [PATCH 115/418] ignore gverb warnings --- libraries/audio-client/src/AudioClient.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 674d2f043e..b528b67745 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -38,11 +38,20 @@ #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif +#ifdef WIN32 +#pragma warning (push) +#pragma warning (disable: 4273 4305) +#endif + extern "C" { #include #include } +#ifdef WIN32 +#pragma warning (pop) +#endif + #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif From 2eaeb26b2ae7475e11b45a6103e11e1841d9d2f6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 24 Sep 2015 09:14:51 -0700 Subject: [PATCH 116/418] fix GetVersionEx warning --- interface/src/devices/3DConnexionClient.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/devices/3DConnexionClient.cpp b/interface/src/devices/3DConnexionClient.cpp index b6f2aa8718..d49fafa3e0 100755 --- a/interface/src/devices/3DConnexionClient.cpp +++ b/interface/src/devices/3DConnexionClient.cpp @@ -160,6 +160,8 @@ ConnexionClient& ConnexionClient::getInstance() { #ifdef Q_OS_WIN +#include + void ConnexionClient::toggleConnexion(bool shouldEnable) { ConnexionData& connexiondata = ConnexionData::getInstance(); if (shouldEnable && connexiondata.getDeviceID() == 0) { @@ -425,18 +427,13 @@ bool ConnexionClient::InitializeRawInput(HWND hwndTarget) { return false; } - // FIXME - http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprecation-of-GetVe - // Get OS version. - OSVERSIONINFO osvi = { sizeof(OSVERSIONINFO), 0 }; - ::GetVersionEx(&osvi); - unsigned int cbSize = sizeof(devicesToRegister[0]); for (size_t i = 0; i < numDevices; i++) { // Set the target window to use //devicesToRegister[i].hwndTarget = hwndTarget; // If Vista or newer, enable receiving the WM_INPUT_DEVICE_CHANGE message. - if (osvi.dwMajorVersion >= 6) { + if (IsWindowsVistaOrGreater()) { devicesToRegister[i].dwFlags |= RIDEV_DEVNOTIFY; } } From f334651a57eab4dccd07db87cc705a8477d6eb85 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 10:05:27 -0700 Subject: [PATCH 117/418] deleted handControllerGrab --- examples/controllers/handControllerGrab.js | 463 --------------------- 1 file changed, 463 deletions(-) delete mode 100644 examples/controllers/handControllerGrab.js diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js deleted file mode 100644 index 251d78e273..0000000000 --- a/examples/controllers/handControllerGrab.js +++ /dev/null @@ -1,463 +0,0 @@ -// hydraGrab.js -// examples -// -// Created by Eric Levin on 9/2/15 -// Copyright 2015 High Fidelity, Inc. -// -// Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -Script.include("../libraries/utils.js"); - - -///////////////////////////////////////////////////////////////// -// -// these tune time-averaging and "on" value for analog trigger -// - -var TRIGGER_SMOOTH_RATIO = 0.1; // 0.0 disables smoothing of trigger value -var TRIGGER_ON_VALUE = 0.2; - -///////////////////////////////////////////////////////////////// -// -// distant manipulation -// - -var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object -var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position -var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { - red: 10, - green: 10, - blue: 255 -}; // line color when pick misses -var INTERSECT_COLOR = { - red: 250, - green: 10, - blue: 10 -}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = { - x: 1000, - y: 1000, - z: 1000 -}; -var LINE_LENGTH = 500; - - -///////////////////////////////////////////////////////////////// -// -// near grabbing -// - -var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected -var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position -var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. -var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected -var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things - -///////////////////////////////////////////////////////////////// -// -// other constants -// - -var RIGHT_HAND = 1; -var LEFT_HAND = 0; - -var ZERO_VEC = { - x: 0, - y: 0, - z: 0 -}; -var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; -var MSEC_PER_SEC = 1000.0; - -// these control how long an abandoned pointer line will hang around -var startTime = Date.now(); -var LIFETIME = 10; - -// states for the state machine -var STATE_SEARCHING = 0; -var STATE_DISTANCE_HOLDING = 1; -var STATE_CONTINUE_DISTANCE_HOLDING = 2; -var STATE_NEAR_GRABBING = 3; -var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_RELEASE = 5; - -var GRAB_USER_DATA_KEY = "grabKey"; - -function controller(hand, triggerAction) { - this.hand = hand; - if (this.hand === RIGHT_HAND) { - this.getHandPosition = MyAvatar.getRightPalmPosition; - this.getHandRotation = MyAvatar.getRightPalmRotation; - } else { - this.getHandPosition = MyAvatar.getLeftPalmPosition; - this.getHandRotation = MyAvatar.getLeftPalmRotation; - } - this.triggerAction = triggerAction; - this.palm = 2 * hand; - // this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed - - this.actionID = null; // action this script created... - this.grabbedEntity = null; // on this entity. - this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity - this.state = 0; - this.pointer = null; // entity-id of line object - this.triggerValue = 0; // rolling average of trigger value - - this.update = function() { - switch (this.state) { - case STATE_SEARCHING: - this.search(); - break; - case STATE_DISTANCE_HOLDING: - this.distanceHolding(); - break; - case STATE_CONTINUE_DISTANCE_HOLDING: - this.continueDistanceHolding(); - break; - case STATE_NEAR_GRABBING: - this.nearGrabbing(); - break; - case STATE_CONTINUE_NEAR_GRABBING: - this.continueNearGrabbing(); - break; - case STATE_RELEASE: - this.release(); - break; - } - } - - - this.lineOn = function(closePoint, farPoint, color) { - // draw a line - if (this.pointer == null) { - this.pointer = Entities.addEntity({ - type: "Line", - name: "pointer", - dimensions: LINE_ENTITY_DIMENSIONS, - visible: true, - position: closePoint, - linePoints: [ZERO_VEC, farPoint], - color: color, - lifetime: LIFETIME - }); - } else { - Entities.editEntity(this.pointer, { - position: closePoint, - linePoints: [ZERO_VEC, farPoint], - color: color, - lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME - }); - } - } - - - this.lineOff = function() { - if (this.pointer != null) { - Entities.deleteEntity(this.pointer); - } - this.pointer = null; - } - - - this.triggerSmoothedSqueezed = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - // smooth out trigger value - this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + - (triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO)); - return this.triggerValue > TRIGGER_ON_VALUE; - } - - - this.triggerSqueezed = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - return triggerValue > TRIGGER_ON_VALUE; - } - - - this.search = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - // the trigger is being pressed, do a ray test - var handPosition = this.getHandPosition(); - var pickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) - }; - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects && - intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0) { - // the ray is intersecting something we can move. - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); - this.grabbedEntity = intersection.entityID; - if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { - // the hand is very close to the intersected object. go into close-grabbing mode. - this.state = STATE_NEAR_GRABBING; - } else { - // the hand is far from the intersected object. go into distance-holding mode - this.state = STATE_DISTANCE_HOLDING; - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } - } else { - // forward ray test failed, try sphere test. - var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); - var minDistance = GRAB_RADIUS; - var grabbedEntity = null; - for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i]); - var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer" && - props.collisionsWillMove === 1 && - props.locked === 0) { - this.grabbedEntity = nearbyEntities[i]; - minDistance = distance; - } - } - if (this.grabbedEntity === null) { - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else { - this.state = STATE_NEAR_GRABBING; - } - } - } - - - this.distanceHolding = function() { - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - // add the action and initialize some variables - this.currentObjectPosition = grabbedProperties.position; - this.currentObjectRotation = grabbedProperties.rotation; - this.currentObjectTime = Date.now(); - this.handPreviousPosition = handControllerPosition; - this.handPreviousRotation = handRotation; - - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME - }); - if (this.actionID == NULL_ACTION_ID) { - this.actionID = null; - } - - if (this.actionID != null) { - this.state = STATE_CONTINUE_DISTANCE_HOLDING; - this.activateEntity(this.grabbedEntity); - Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); - - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - } - } - - - this.continueDistanceHolding = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - var handPosition = this.getHandPosition(); - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR); - - // the action was set up on a previous call. update the targets. - var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); - - var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); - this.handPreviousPosition = handControllerPosition; - var superHandMoved = Vec3.multiply(handMoved, radius); - - var newObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved); - var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters - var now = Date.now(); - var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, false); - - this.currentObjectPosition = newObjectPosition; - this.currentObjectTime = now; - - // this doubles hand rotation - var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); - this.handPreviousRotation = handRotation; - this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); - - Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab"); - - Entities.updateAction(this.grabbedEntity, this.actionID, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME - }); - } - - - this.nearGrabbing = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - this.lineOff(); - - this.activateEntity(this.grabbedEntity); - - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - var handRotation = this.getHandRotation(); - var handPosition = this.getHandPosition(); - - var objectRotation = grabbedProperties.rotation; - var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); - - currentObjectPosition = grabbedProperties.position; - var offset = Vec3.subtract(currentObjectPosition, handPosition); - var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); - - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand == RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation - }); - if (this.actionID == NULL_ACTION_ID) { - this.actionID = null; - } else { - this.state = STATE_CONTINUE_NEAR_GRABBING; - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - } - - this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm); - this.currentObjectTime = Date.now(); - } - - - this.continueNearGrabbing = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - // keep track of the measured velocity of the held object - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var now = Date.now(); - - var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerPosition); // meters - var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, true); - - this.currentHandControllerPosition = handControllerPosition; - this.currentObjectTime = now; - Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - } - - - this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) { - if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) { - var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime); - // don't update grabbedVelocity if the trigger is off. the smoothing of the trigger - // value would otherwise give the held object time to slow down. - if (this.triggerSqueezed()) { - this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); - } - - if (useMultiplier) { - this.grabbedVelocity = Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER); - } - } - } - - - this.release = function() { - this.lineOff(); - - if (this.grabbedEntity != null && this.actionID != null) { - Entities.deleteAction(this.grabbedEntity, this.actionID); - Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); - } - - // the action will tend to quickly bring an object's velocity to zero. now that - // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, { - velocity: this.grabbedVelocity - }); - this.deactivateEntity(this.grabbedEntity); - - this.grabbedVelocity = ZERO_VEC; - this.grabbedEntity = null; - this.actionID = null; - this.state = STATE_SEARCHING; - } - - - this.cleanup = function() { - release(); - } - - this.activateEntity = function(entity) { - var data = { - activated: true, - avatarId: MyAvatar.sessionUUID - }; - setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } - - this.deactivateEntity = function(entity) { - var data = { - activated: false, - avatarId: null - }; - setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } -} - - -var rightController = new controller(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); -var leftController = new controller(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); - - -function update() { - rightController.update(); - leftController.update(); -} - - -function cleanup() { - rightController.cleanup(); - leftController.cleanup(); -} - - -Script.scriptEnding.connect(cleanup); -Script.update.connect(update) \ No newline at end of file From 1e1cfb6aae197aa5af6828a768a064c1471b87dd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 10:15:50 -0700 Subject: [PATCH 118/418] Flipped lights so up is lights on and vica versa --- examples/toys/lightSwitchGarage.js | 33 ++++++++++++++++++--------- examples/toys/lightSwitchHall.js | 36 ++++++++++++++++++------------ 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index a68a09cf7d..99d827aa06 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -52,16 +52,7 @@ this.createLights(); } - // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = {x: 0, y: 1, z: 0}; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); + this.flipLights(); Audio.playSound(this.switchSound, { volume: 0.5, @@ -86,7 +77,7 @@ }, createLights: function() { - + var sconceLight3 = Entities.addEntity({ type: "Light", @@ -176,6 +167,25 @@ }, + flipLights: function() { + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + + }, + + // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { @@ -191,6 +201,7 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); + this.flipLights(); } //If lights are on, do nothing! }, diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 6bc1eeab83..49ccc51b79 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -53,19 +53,7 @@ } // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); + this.flipLights(); Audio.playSound(this.switchSound, { volume: 0.5, @@ -148,9 +136,27 @@ }, + flipLights: function() { + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + + }, + // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: - preload: function(entityID) { + preload: function(entityID) { this.entityID = entityID; //The light switch is static, so just cache its position once @@ -163,6 +169,8 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); + this.flipLights(); + } //If lights are on, do nothing! }, From 8609769c2081f539f2b0c8fdeafabd032f7f1f38 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 11:58:54 -0700 Subject: [PATCH 119/418] cat now listens for touch event from controller --- examples/toys/cat.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 1f1e7cc9d4..f1fcb81e8f 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -27,17 +27,10 @@ Cat.prototype = { - update: function() { - var leftHandPosition = MyAvatar.getLeftPalmPosition(); - var rightHandPosition = MyAvatar.getRightPalmPosition(); - if (Vec3.distance(leftHandPosition, _this.position) < _this.distanceThreshold || Vec3.distance(rightHandPosition, _this.position) < _this.distanceThreshold && _this.canMeow) { - _this.meow(); - _this.canMeow = false; - Script.setTimeout(function() { - _this.canMeow = true - }, _this.meowBreakTime) - } - }, + startTouch: function() { + print("START TOUCH") + this.meow(); + } meow: function() { From 17e3e9394fbae1af48e93eefc8acb4ef45fc3604 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Sep 2015 12:33:11 -0700 Subject: [PATCH 120/418] allow head translation for 3rd person screenie IK --- .../defaultAvatar_full/avatar-animation.json | 3 +- interface/src/avatar/MyAvatar.cpp | 1 - .../animation/src/AnimInverseKinematics.cpp | 133 ++++++++++-------- .../animation/src/AnimInverseKinematics.h | 24 +++- libraries/animation/src/AnimNodeLoader.cpp | 3 +- libraries/animation/src/AnimOverlay.cpp | 4 +- libraries/animation/src/Rig.cpp | 2 + 7 files changed, 101 insertions(+), 69 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 550a95e980..edde635176 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -31,7 +31,8 @@ { "jointName": "Head", "positionVar": "headPosition", - "rotationVar": "headRotation" + "rotationVar": "headRotation", + "typeVar": "headType" } ] }, diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c499f9f5bb..00ced2eb13 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -141,7 +141,6 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { } void MyAvatar::reset() { - _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index e31f7795f3..7f32d8a2fa 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -42,9 +42,8 @@ void AnimInverseKinematics::loadPoses(const AnimPoseVec& poses) { void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) const { int numJoints = (int)_relativePoses.size(); - absolutePoses.clear(); - absolutePoses.resize(numJoints); assert(numJoints <= _skeleton->getNumJoints()); + assert(numJoints == (int)absolutePoses.size()); for (int i = 0; i < numJoints; ++i) { int parentIndex = _skeleton->getParentIndex(i); if (parentIndex < 0) { @@ -55,7 +54,11 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con } } -void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar) { +void AnimInverseKinematics::setTargetVars( + const QString& jointName, + const QString& positionVar, + const QString& rotationVar, + const QString& typeVar) { // if there are dups, last one wins. bool found = false; for (auto& targetVar: _targetVarVec) { @@ -63,13 +66,14 @@ void AnimInverseKinematics::setTargetVars(const QString& jointName, const QStrin // update existing targetVar targetVar.positionVar = positionVar; targetVar.rotationVar = rotationVar; + targetVar.typeVar = typeVar; found = true; break; } } if (!found) { // create a new entry - _targetVarVec.push_back(IKTargetVar(jointName, positionVar, rotationVar)); + _targetVarVec.push_back(IKTargetVar(jointName, positionVar, rotationVar, typeVar)); } } @@ -86,6 +90,7 @@ static int findRootJointInSkeleton(AnimSkeleton::ConstPointer skeleton, int inde void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::vector& targets) { // build a list of valid targets from _targetVarVec and animVars + _maxTargetIndex = -1; bool removeUnfoundJoints = false; for (auto& targetVar : _targetVarVec) { if (targetVar.jointIndex == -1) { @@ -100,14 +105,17 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: removeUnfoundJoints = true; } } else { - // TODO: get this done without a double-lookup of each var in animVars IKTarget target; AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, _relativePoses); target.pose.trans = animVars.lookup(targetVar.positionVar, defaultPose.trans); target.pose.rot = animVars.lookup(targetVar.rotationVar, defaultPose.rot); + target.setType(animVars.lookup(targetVar.typeVar, QString(""))); target.rootIndex = targetVar.rootIndex; target.index = targetVar.jointIndex; targets.push_back(target); + if (target.index > _maxTargetIndex) { + _maxTargetIndex = target.index; + } } } @@ -129,9 +137,10 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } } -void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vector& targets) { +void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector& targets) { // compute absolute poses that correspond to relative target poses AnimPoseVec absolutePoses; + absolutePoses.resize(_relativePoses.size()); computeAbsolutePoses(absolutePoses); // clear the accumulators before we start the IK solver @@ -139,25 +148,23 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vectorgetParentIndex(tipIndex); - while (pivotIndex != -1 && error > ACCEPTABLE_RELATIVE_ERROR) { + float fractionDenominator = 1.0f; + while (pivotIndex != -1) { // compute the two lines that should be aligned glm::vec3 jointPosition = absolutePoses[pivotIndex].trans; glm::vec3 leverArm = tip - jointPosition; @@ -166,59 +173,60 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vector EPSILON) { + glm::quat deltaRotation; + const float MIN_AXIS_LENGTH = 1.0e-4f; + if (axisLength > MIN_AXIS_LENGTH) { // compute deltaRotation for alignment (brings tip closer to target) axis /= axisLength; float angle = acosf(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine))); // NOTE: even when axisLength is not zero (e.g. lever-arm and pivot-arm are not quite aligned) it is // still possible for the angle to be zero so we also check that to avoid unnecessary calculations. - if (angle > EPSILON) { + const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; + if (angle > MIN_ADJUSTMENT_ANGLE) { // reduce angle by half: slows convergence but adds stability to IK solution - angle = 0.5f * angle; - glm::quat deltaRotation = glm::angleAxis(angle, axis); - - int parentIndex = _skeleton->getParentIndex(pivotIndex); - if (parentIndex == -1) { - // TODO? apply constraints to root? - // TODO? harvest the root's transform as movement of entire skeleton? - } else { - // compute joint's new parent-relative rotation - // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q - glm::quat newRot = glm::normalize(glm::inverse( - absolutePoses[parentIndex].rot) * - deltaRotation * - absolutePoses[pivotIndex].rot); - RotationConstraint* constraint = getConstraint(pivotIndex); - if (constraint) { - bool constrained = constraint->apply(newRot); - if (constrained) { - // the constraint will modify the movement of the tip so we have to compute the modified - // model-frame deltaRotation - // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ - deltaRotation = absolutePoses[parentIndex].rot * - newRot * - glm::inverse(absolutePoses[pivotIndex].rot); - } - } - // store the rotation change in the accumulator - _accumulators[pivotIndex].add(newRot); - } - // this joint has been changed so we check to see if it has the lowest index - if (pivotIndex < lowestMovedIndex) { - lowestMovedIndex = pivotIndex; - } - - // keep track of tip's new position as we descend towards root - tip = jointPosition + deltaRotation * leverArm; - error = glm::length(targetPose.trans - tip); + angle /= fractionDenominator; + deltaRotation = glm::angleAxis(angle, axis); } } + fractionDenominator++; + + int parentIndex = _skeleton->getParentIndex(pivotIndex); + if (parentIndex == -1) { + // TODO? apply constraints to root? + // TODO? harvest the root's transform as movement of entire skeleton? + } else { + // compute joint's new parent-relative rotation + // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q + glm::quat newRot = glm::normalize(glm::inverse( + absolutePoses[parentIndex].rot) * + deltaRotation * + absolutePoses[pivotIndex].rot); + RotationConstraint* constraint = getConstraint(pivotIndex); + if (constraint) { + bool constrained = constraint->apply(newRot); + if (constrained) { + // the constraint will modify the movement of the tip so we have to compute the modified + // model-frame deltaRotation + // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ + deltaRotation = absolutePoses[parentIndex].rot * + newRot * + glm::inverse(absolutePoses[pivotIndex].rot); + } + } + // store the rotation change in the accumulator + _accumulators[pivotIndex].add(newRot); + } + // this joint has been changed so we check to see if it has the lowest index + if (pivotIndex < lowestMovedIndex) { + lowestMovedIndex = pivotIndex; + } + + // keep track of tip's new position as we descend towards root + tip = jointPosition + deltaRotation * leverArm; + pivotIndex = _skeleton->getParentIndex(pivotIndex); } - if (largestError < error) { - largestError = error; - } } ++numLoops; @@ -238,7 +246,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vector ACCEPTABLE_RELATIVE_ERROR && numLoops < MAX_IK_LOOPS && usecTimestampNow() < expiry); + } while (numLoops < MAX_IK_LOOPS); // finally set the relative rotation of each tip to agree with absolute target rotation for (auto& target: targets) { @@ -380,7 +388,7 @@ void AnimInverseKinematics::initConstraints() { } } - _constraints.clear(); + clearConstraints(); for (int i = 0; i < numJoints; ++i) { // compute the joint's baseName and remember whether its prefix was "Left" or not QString baseName = _skeleton->getJointName(i); @@ -639,9 +647,12 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele targetVar.jointIndex = -1; } - _maxTargetIndex = 0; + _maxTargetIndex = -1; + + for (auto& accumulator: _accumulators) { + accumulator.clearAndClean(); + } - _accumulators.clear(); if (skeleton) { initConstraints(); } else { diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 70808f5919..9d0fd0f557 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -31,20 +31,33 @@ public: void loadPoses(const AnimPoseVec& poses); void computeAbsolutePoses(AnimPoseVec& absolutePoses) const; - void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar); + void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, const QString& typeVar); virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, float dt, AnimNode::Triggers& triggersOut) override; virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override; protected: struct IKTarget { + enum class Type { + RotationAndPosition, + RotationOnly + }; AnimPose pose; int index; int rootIndex; + Type type = Type::RotationAndPosition; + + void setType(const QString& typeVar) { + if (typeVar == "RotationOnly") { + type = Type::RotationOnly; + } else { + type = Type::RotationAndPosition; + } + } }; void computeTargets(const AnimVariantMap& animVars, std::vector& targets); - void solveWithCyclicCoordinateDescent(std::vector& targets); + void solveWithCyclicCoordinateDescent(const std::vector& targets); virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton); // for AnimDebugDraw rendering @@ -55,15 +68,20 @@ protected: void initConstraints(); struct IKTargetVar { - IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn) : + IKTargetVar(const QString& jointNameIn, + const QString& positionVarIn, + const QString& rotationVarIn, + const QString& typeVarIn) : positionVar(positionVarIn), rotationVar(rotationVarIn), + typeVar(typeVarIn), jointName(jointNameIn), jointIndex(-1), rootIndex(-1) {} QString positionVar; QString rotationVar; + QString typeVar; QString jointName; int jointIndex; // cached joint index int rootIndex; // cached root index diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index b2afae4728..147025f1cf 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -342,8 +342,9 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS READ_STRING(jointName, targetObj, id, jsonUrl, nullptr); READ_STRING(positionVar, targetObj, id, jsonUrl, nullptr); READ_STRING(rotationVar, targetObj, id, jsonUrl, nullptr); + READ_OPTIONAL_STRING(typeVar, targetObj); - node->setTargetVars(jointName, positionVar, rotationVar); + node->setTargetVars(jointName, positionVar, rotationVar, typeVar); }; return node; diff --git a/libraries/animation/src/AnimOverlay.cpp b/libraries/animation/src/AnimOverlay.cpp index 08c4304b08..8f60b972ce 100644 --- a/libraries/animation/src/AnimOverlay.cpp +++ b/libraries/animation/src/AnimOverlay.cpp @@ -51,8 +51,8 @@ const AnimPoseVec& AnimOverlay::evaluate(const AnimVariantMap& animVars, float d _alpha = animVars.lookup(_alphaVar, _alpha); if (_children.size() >= 2) { - auto underPoses = _children[1]->evaluate(animVars, dt, triggersOut); - auto overPoses = _children[0]->overlay(animVars, dt, triggersOut, underPoses); + auto& underPoses = _children[1]->evaluate(animVars, dt, triggersOut); + auto& overPoses = _children[0]->overlay(animVars, dt, triggersOut, underPoses); if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) { _poses.resize(underPoses.size()); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f1e81df64e..770e857c4a 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1065,6 +1065,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.set("headPosition", headPos); _animVars.set("headRotation", headRot); + _animVars.set("headType", QString("RotationAndPosition")); _animVars.set("neckPosition", neckPos); _animVars.set("neckRotation", neckRot); @@ -1077,6 +1078,7 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) { _animVars.unset("headPosition"); _animVars.set("headRotation", realLocalHeadOrientation); + _animVars.set("headType", QString("RotationOnly")); _animVars.unset("neckPosition"); _animVars.unset("neckRotation"); } From 6d4e4af0a5677afa41afdabf68b78334c0804f04 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 24 Sep 2015 22:02:22 +0200 Subject: [PATCH 121/418] ability to see Stats in JavaScript + example script which outputs the stats to the console/logviewer --- examples/example/misc/statsExample.js | 67 +++++++++++++++++++++++++++ interface/src/Application.cpp | 1 + interface/src/ui/Stats.cpp | 24 +++++----- interface/src/ui/Stats.h | 6 ++- 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 examples/example/misc/statsExample.js diff --git a/examples/example/misc/statsExample.js b/examples/example/misc/statsExample.js new file mode 100644 index 0000000000..3c677af96a --- /dev/null +++ b/examples/example/misc/statsExample.js @@ -0,0 +1,67 @@ +// +// statsExample.js +// examples/example/misc +// +// Created by Thijs Wenker on 24 Sept 2015 +// Copyright 2015 High Fidelity, Inc. +// +// Prints the stats to the console. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// The stats to be displayed +var stats = [ + 'serverCount', + 'framerate', // a.k.a. FPS + 'simrate', + 'avatarSimrate', + 'avatarCount', + 'packetInCount', + 'packetOutCount', + 'mbpsIn', + 'mbpsOut', + 'audioPing', + 'avatarPing', + 'entitiesPing', + 'assetPing', + 'velocity', + 'yaw', + 'avatarMixerKbps', + 'avatarMixerPps', + 'audioMixerKbps', + 'audioMixerPps', + 'downloads', + 'downloadsPending', + 'triangles', + 'quads', + 'materialSwitches', + 'meshOpaque', + 'meshTranslucent', + 'opaqueConsidered', + 'opaqueOutOfView', + 'opaqueTooSmall', + 'translucentConsidered', + 'translucentOutOfView', + 'translucentTooSmall', + 'sendingMode', + 'packetStats', + 'lodStatus', + 'timingStats', + 'serverElements', + 'serverInternal', + 'serverLeaves', + 'localElements', + 'localInternal', + 'localLeaves' +]; + +// Force update the stats, in case the stats panel is invisible +Stats.forceUpdateStats(); + +// Loop through the stats and display them +for (var i in stats) { + var stat = stats[i]; + print(stat + " = " + Stats[stat]); +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c359275d8a..14dfaa3783 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4063,6 +4063,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerFunction("WebWindow", WebWindowClass::constructor, 1); scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance()); + scriptEngine->registerGlobalObject("Stats", Stats::getInstance()); scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 4dd552210c..ebce4f2b96 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -89,14 +89,14 @@ bool Stats::includeTimingRecord(const QString& name) { } -void Stats::updateStats() { - if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { - if (isVisible()) { - setVisible(false); - } - return; - } else { - if (!isVisible()) { +void Stats::updateStats(bool force) { + if (!force) { + if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { + if (isVisible()) { + setVisible(false); + } + return; + } else if (!isVisible()) { setVisible(true); } } @@ -161,7 +161,7 @@ void Stats::updateStats() { STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z)); STAT_UPDATE_FLOAT(velocity, glm::length(myAvatar->getVelocity()), 0.1f); STAT_UPDATE_FLOAT(yaw, myAvatar->getBodyYaw(), 0.1f); - if (_expanded) { + if (_expanded || force) { SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { STAT_UPDATE(avatarMixerKbps, roundf( @@ -175,7 +175,7 @@ void Stats::updateStats() { STAT_UPDATE(avatarMixerPps, -1); } SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); - if (audioMixerNode) { + if (audioMixerNode || force) { STAT_UPDATE(audioMixerKbps, roundf( bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) + bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer))); @@ -230,7 +230,7 @@ void Stats::updateStats() { totalLeaves += stats.getTotalLeaves(); } } - if (_expanded) { + if (_expanded || force) { if (serverCount == 0) { sendingModeStream << "---"; } @@ -272,7 +272,7 @@ void Stats::updateStats() { STAT_UPDATE(serverElements, (int)totalNodes); STAT_UPDATE(localElements, (int)OctreeElement::getNodeCount()); - if (_expanded) { + if (_expanded || force) { STAT_UPDATE(serverInternal, (int)totalInternal); STAT_UPDATE(serverLeaves, (int)totalLeaves); // Local Voxels diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index e5c273926b..2e4c5e4dca 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -81,7 +81,7 @@ public: const QString& monospaceFont() { return _monospaceFont; } - void updateStats(); + void updateStats(bool force = false); bool isExpanded() { return _expanded; } bool isTimingExpanded() { return _timingExpanded; } @@ -93,6 +93,9 @@ public: } } +public slots: + void forceUpdateStats() { updateStats(true); } + signals: void expandedChanged(); void timingExpandedChanged(); @@ -149,3 +152,4 @@ private: }; #endif // hifi_Stats_h + From 59da684eb94dc59e82f95d66cee6d8457a659407 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 24 Sep 2015 13:15:03 -0700 Subject: [PATCH 122/418] make IKTarget::setType() a one-liner --- interface/src/avatar/MyAvatar.cpp | 1 + libraries/animation/src/AnimInverseKinematics.h | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 00ced2eb13..c499f9f5bb 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -141,6 +141,7 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { } void MyAvatar::reset() { + _skeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 9d0fd0f557..121b35bd9d 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -47,13 +47,7 @@ protected: int rootIndex; Type type = Type::RotationAndPosition; - void setType(const QString& typeVar) { - if (typeVar == "RotationOnly") { - type = Type::RotationOnly; - } else { - type = Type::RotationAndPosition; - } - } + void setType(const QString& typeVar) { type = ((typeVar == "RotationOnly") ? Type::RotationOnly : Type::RotationAndPosition); } }; void computeTargets(const AnimVariantMap& animVars, std::vector& targets); From 2883319fb0fe4d3810df53983262c850830dda7c Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 13:33:43 -0700 Subject: [PATCH 123/418] Add potted plant, arm chair, and pillow --- examples/toys/masterResetEntity.js | 195 +++++++++++++++++++++++------ 1 file changed, 158 insertions(+), 37 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..901777be09 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -8,7 +8,7 @@ /*global deleteAllToys, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ //per script -/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ +/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches,createPottedPlant,createArmChair,createPillow */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); @@ -455,41 +455,41 @@ function createBlocks(position) { var i, j; var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }]; + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -527,12 +527,133 @@ function createBlocks(position) { } } +//createPottedPlant,createArmChair,createPillow + +function createPottedPlant() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; + + var position = { + x: 554.26, + y: 495.23, + z: 504.53 + } + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10 + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + linearDamping: 0.4 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createArmChair() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair.fbx"; + var position = { + x: 549.39, + y: 494.57, + z: 508.37 + } + + var ARM_CHAIR_COLLISION_SHAPE = ""; + var entity = Entities.addEntity({ + type: "Model", + name: "Arm Chair", + modelURL: modelURL, + shapeType:'compound', + compoundShapeURL: ARM_CHAIR_COLLISION_SHAPE, + position: position, + rotation: { + x: 0, + y: -143.01, + z: 0 + }, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createPillow() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair_pillow.fbx"; + var position = { + x: 549.39, + y: 495.00, + z: 508.37 + } + var entity = Entities.addEntity({ + type: "Model", + name: "Arm Chair Pillow", + modelURL: modelURL, + position: position, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + function cleanup() { deleteAllToys(); } if (shouldDeleteOnEndScript) { - Script.scriptEnding.connect(cleanup); } From 16f9140a08ca4dacb34805eb644958caab439e02 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:04:37 -0700 Subject: [PATCH 124/418] updated master script so objects with fewer properties are on one line --- examples/toys/masterResetEntity.js | 344 +++++------------------------ 1 file changed, 60 insertions(+), 284 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..eebcefaaed 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -24,54 +24,24 @@ deleteAllToys(); createAllToys(); function createAllToys() { - createBlocks({ - x: 548.3, - y: 495.55, - z: 504.4 - }); + createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); - createSprayCan({ - x: 549.8, - y: 495.6, - z: 503.94 - }); + createSprayCan({ x: 549.8, y: 495.6, z: 503.94 }); - createBasketBall({ - x: 547.73, - y: 495.5, - z: 505.47 - }); + createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); - createDoll({ - x: 546.67, - y: 495.41, - z: 505.09 - }); + createDoll({x: 546.67, y: 495.41, z: 505.09}); - createWand({ - x: 546.71, - y: 495.55, - z: 506.15 - }); + createWand({ x: 546.71, y: 495.55, z: 506.15}); createDice(); - createFlashlight({ - x: 545.72, - y: 495.41, - z: 505.78 + createFlashlight({ x: 545.72, y: 495.41, z: 505.78 }); - createCat({ - x: 551.49859619140625, - y: 495.49111938476562, - z: 502.26498413085938 - }); + createCat({ x: 551.49859619140625, y: 495.49111938476562, z: 502.26498413085938 }); - createMagballs({ - x: 548.73, - y: 495.51, - z: 503.54 + createMagballs({ x: 548.73, y: 495.51, z: 503.54 }); //Handles toggling of all sconce lights @@ -99,36 +69,21 @@ function createMagballs(position) { modelURL: modelURL, name: "Tin Can", position: position, - rotation: { - w: 0.93041884899139404, - x: -1.52587890625e-05, - y: 0.36647593975067139, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.16946873068809509, - y: 0.21260403096675873, - z: 0.16946862637996674 - }, + rotation: { w: 0.93041884899139404, x: -1.52587890625e-05, y: 0.36647593975067139, z: -1.52587890625e-05}, + dimensions: { x: 0.16946873068809509, y: 0.21260403096675873, z: 0.16946862637996674 }, }); - setEntityCustomData(resetKey, tinCan, { - resetMe: true - }); + setEntityCustomData(resetKey, tinCan, { resetMe: true }); - setEntityCustomData("OmniTool", tinCan, { - script: "../toys/magBalls.js" - }); + setEntityCustomData("OmniTool", tinCan, { script: "../toys/magBalls.js"}); } function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ - running: true, - }); + var animationSettings = JSON.stringify({running: true,}); var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -137,22 +92,11 @@ function createCat(position) { animationURL: animationURL, animationSettings: animationSettings, position: position, - rotation: { - w: 0.35020983219146729, - x: -4.57763671875e-05, - y: 0.93664455413818359, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.15723302960395813, - y: 0.50762706995010376, - z: 0.90716040134429932 - }, + rotation: { w: 0.35020983219146729, x: -4.57763671875e-05, y: 0.93664455413818359, z: -1.52587890625e-05}, + dimensions: { x: 0.15723302960395813, y: 0.50762706995010376, z: 0.90716040134429932}, }); - setEntityCustomData(resetKey, cat, { - resetMe: true - }); + setEntityCustomData(resetKey, cat, { resetMe: true }); } function createFlashlight(position) { @@ -165,28 +109,14 @@ function createFlashlight(position) { name: "flashlight", script: scriptURL, position: position, - dimensions: { - x: 0.08, - y: 0.30, - z: 0.08 - }, + dimensions: { x: 0.08, y: 0.30, z: 0.08}, collisionsWillMove: true, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: { x: 0, y: -0.01, z: 0}, shapeType: 'box', }); - setEntityCustomData(resetKey, flashlight, { - resetMe: true - }); + setEntityCustomData(resetKey, flashlight, {resetMe: true}); } @@ -199,22 +129,9 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, - rotation: { - w: 0.63280689716339111, - x: 0.63280689716339111, - y: -0.31551080942153931, - z: 0.31548023223876953 - }, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - } + position: {x: 543.27764892578125, y: 495.67999267578125, z: 511.00564575195312}, + rotation: {w: 0.63280689716339111, x: 0.63280689716339111, y: -0.31551080942153931, z: 0.31548023223876953}, + dimensions: {x: 0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} }); setEntityCustomData(resetKey, lightSwitchHall, { @@ -228,27 +145,12 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Garage", script: scriptURL, - position: { - x: 545.62, - y: 495.68, - z: 500.21 - }, - rotation: { - w: 0.20082402229309082, - x: 0.20082402229309082, - y: -0.67800414562225342, - z: 0.67797362804412842 - }, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - } + position: {x: 545.62, y: 495.68,z: 500.21}, + rotation: { w: 0.20082402229309082, x: 0.20082402229309082, y: -0.67800414562225342, z: 0.67797362804412842}, + dimensions: { x:0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} }); - setEntityCustomData(resetKey, lightSwitchGarage, { - resetMe: true - }); + setEntityCustomData(resetKey, lightSwitchGarage, {resetMe: true}); } @@ -258,46 +160,22 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: { - x: 541, - y: 494.96, - z: 509.1 - }, - dimensions: { - x: 0.09, - y: 0.09, - z: 0.09 - }, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + position: {x: 541, y: 494.96, z: 509.1}, + dimensions: {x: 0.09, y: 0.09, z: 0.09}, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: {x: 0,y: -0.01, z: 0}, shapeType: "box", collisionsWillMove: true }; var dice1 = Entities.addEntity(diceProps); - diceProps.position = { - x: 541.05, - y: 494.96, - z: 509.0 - }; + diceProps.position = { x: 541.05, y: 494.96, z: 509.0 }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, { - resetMe: true - }); + setEntityCustomData(resetKey, dice1, {resetMe: true}); - setEntityCustomData(resetKey, dice2, { - resetMe: true - }); + setEntityCustomData(resetKey, dice2, {resetMe: true}); } function createWand(position) { @@ -311,16 +189,8 @@ function createWand(position) { type: "Model", modelURL: WAND_MODEL, position: position, - gravity: { - x: 0, - y: 0, - z: 0, - }, - dimensions: { - x: 0.05, - y: 0.25, - z: 0.05 - }, + gravity: {x: 0, y: 0, z: 0}, + dimensions: { x: 0.05, y: 0.25,z: 0.05}, //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, @@ -330,9 +200,7 @@ function createWand(position) { script: scriptURL }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createBasketBall(position) { @@ -346,41 +214,22 @@ function createBasketBall(position) { collisionsWillMove: true, shapeType: "sphere", name: "basketball", - dimensions: { - x: 0.25, - y: 0.26, - z: 0.25 - }, - gravity: { - x: 0, - y: -7, - z: 0 - }, + dimensions: {x: 0.25, y: 0.26, z: 0.25}, + gravity: {x: 0, y: -7, z: 0}, restitution: 10, linearDamping: 0.0, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + velocity: { x: 0, y: -0.01, z: 0}, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); - + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var scriptURL = Script.resolvePath("doll.js"); - var naturalDimensions = { - x: 1.63, - y: 1.67, - z: 0.26 - }; + var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -390,22 +239,12 @@ function createDoll(position) { position: position, shapeType: 'box', dimensions: desiredDimensions, - gravity: { - x: 0, - y: -5, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, + gravity: {x: 0, y: -5, z: 0}, + velocity: {x: 0, y: -0.1, z: 0}, collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createSprayCan(position) { @@ -417,35 +256,15 @@ function createSprayCan(position) { name: "spraycan", modelURL: modelURL, position: position, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, + dimensions: {x: 0.07, y: 0.17, z: 0.07}, collisionsWillMove: true, shapeType: 'box', script: scriptURL, - gravity: { - x: 0, - y: -0.5, - z: 0 - }, - velocity: { - x: 0, - y: -1, - z: 0 - } + gravity: {x: 0, y: -0.5, z: 0}, + velocity: { x: 0, y: -1, z: 0} }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } @@ -454,42 +273,13 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; var i, j; - var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }]; + var blockTypes = [ + { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} } + { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} } + { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} } + { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} } + { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} } + ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -498,31 +288,17 @@ function createBlocks(position) { entity = Entities.addEntity({ type: "Model", modelURL: modelURL, - position: Vec3.sum(position, { - x: j / 10, - y: i / 10, - z: 0 - }), + position: Vec3.sum(position, { x: j / 10, y: i / 10, z: 0}), shapeType: 'box', name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - } + gravity: {x: 0, y: -2.5, z: 0}, + velocity: { x: 0, y: -0.01, z: 0} }); //customKey, id, data - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } } } From c1f8cbd1a3c34b26f69336e34a175065a82047c3 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 14:07:15 -0700 Subject: [PATCH 125/418] Remove space before function calls, add spaces before functions --- examples/toys/flashlight/flashlight.js | 82 ++++++++++++-------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/examples/toys/flashlight/flashlight.js b/examples/toys/flashlight/flashlight.js index 5563001d07..9836579afd 100644 --- a/examples/toys/flashlight/flashlight.js +++ b/examples/toys/flashlight/flashlight.js @@ -15,9 +15,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -(function () { +(function() { Script.include("../../libraries/utils.js"); + var ON_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; var OFF_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_off.wav'; @@ -31,22 +32,10 @@ var DISABLE_LIGHT_THRESHOLD = 0.7; // These constants define the Spotlight position and orientation relative to the model - var MODEL_LIGHT_POSITION = { - x: 0, - y: -0.3, - z: 0 - }; - var MODEL_LIGHT_ROTATION = Quat.angleAxis(-90, { - x: 1, - y: 0, - z: 0 - }); + var MODEL_LIGHT_POSITION = { x: 0, y: -0.3, z: 0 }; + var MODEL_LIGHT_ROTATION = Quat.angleAxis(-90, { x: 1, y: 0, z: 0 }); - var GLOW_LIGHT_POSITION = { - x: 0, - y: -0.1, - z: 0 - }; + var GLOW_LIGHT_POSITION = { x: 0, y: -0.1, z: 0}; // Evaluate the world light entity positions and orientations from the model ones function evalLightWorldTransform(modelPos, modelRot) { @@ -64,20 +53,21 @@ }; } - Flashlight.prototype = { lightOn: false, hand: null, whichHand: null, hasSpotlight: false, spotlight: null, - setRightHand: function () { + setRightHand: function() { this.hand = 'RIGHT'; }, - setLeftHand: function () { + + setLeftHand: function() { this.hand = 'LEFT'; }, - startNearGrab: function () { + + startNearGrab: function() { if (!this.hasSpotlight) { //this light casts the beam @@ -117,16 +107,17 @@ cutoff: 90, // in degrees }); - this.hasSpotlight = true; } }, - setWhichHand: function () { + + setWhichHand: function() { this.whichHand = this.hand; }, - continueNearGrab: function () { + + continueNearGrab: function() { if (this.whichHand === null) { //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); @@ -135,7 +126,8 @@ this.changeLightWithTriggerPressure(this.whichHand); } }, - releaseGrab: function () { + + releaseGrab: function() { //delete the lights and reset state if (this.hasSpotlight) { Entities.deleteEntity(this.spotlight); @@ -147,29 +139,28 @@ this.lightOn = false; } }, - updateLightPositions: function () { + + updateLightPositions: function() { var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); //move the two lights along the vectors we set above var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation); - //move them with the entity model Entities.editEntity(this.spotlight, { position: lightTransform.p, rotation: lightTransform.q, }); - Entities.editEntity(this.glowLight, { position: glowLightTransform.p, rotation: glowLightTransform.q, }); }, - changeLightWithTriggerPressure: function (flashLightHand) { + changeLightWithTriggerPressure: function(flashLightHand) { var handClickString = flashLightHand + "_HAND_CLICK"; var handClick = Controller.findAction(handClickString); @@ -183,7 +174,8 @@ } return; }, - turnLightOff: function () { + + turnLightOff: function() { this.playSoundAtCurrentPosition(false); Entities.editEntity(this.spotlight, { intensity: 0 @@ -193,7 +185,8 @@ }); this.lightOn = false; }, - turnLightOn: function () { + + turnLightOn: function() { this.playSoundAtCurrentPosition(true); Entities.editEntity(this.glowLight, { @@ -204,16 +197,8 @@ }); this.lightOn = true; }, - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - preload: function (entityID) { - this.entityID = entityID; - this.ON_SOUND = SoundCache.getSound(ON_SOUND_URL); - this.OFF_SOUND = SoundCache.getSound(OFF_SOUND_URL); - }, - playSoundAtCurrentPosition: function (playOnSound) { + playSoundAtCurrentPosition: function(playOnSound) { var position = Entities.getEntityProperties(this.entityID, "position").position; var audioProperties = { @@ -228,10 +213,21 @@ } }, - // unload() will be called when our entity is no longer available. It may be because we were deleted, - // or because we've left the domain or quit the application. - unload: function () { + preload: function(entityID) { + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * preloading sounds + this.entityID = entityID; + this.ON_SOUND = SoundCache.getSound(ON_SOUND_URL); + this.OFF_SOUND = SoundCache.getSound(OFF_SOUND_URL); + + }, + + unload: function() { + // unload() will be called when our entity is no longer available. It may be because we were deleted, + // or because we've left the domain or quit the application. if (this.hasSpotlight) { Entities.deleteEntity(this.spotlight); Entities.deleteEntity(this.glowLight); @@ -242,8 +238,8 @@ this.lightOn = false; } - }, + }; // entity scripts always need to return a newly constructed object of our type From 536adf898184fc0145147a3f817b2afe75acfd8d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:39:11 -0700 Subject: [PATCH 126/418] testing paintcan --- examples/toys/cat.js | 1 - examples/toys/masterResetEntity.js | 2 +- examples/toys/sprayPaintCan.js | 145 +++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index f1fcb81e8f..98d08969a7 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -28,7 +28,6 @@ Cat.prototype = { startTouch: function() { - print("START TOUCH") this.meow(); } diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..f3950eb32c 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -33,7 +33,7 @@ function createAllToys() { createSprayCan({ x: 549.8, y: 495.6, - z: 503.94 + z: 503.84 }); createBasketBall({ diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 28eb8adaf4..8f3bb12307 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,10 +3,9 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); + GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; - this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); - var TIP_OFFSET_Z = 0.14; var TIP_OFFSET_Y = 0.04; @@ -20,17 +19,59 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - this.setRightHand = function() { - this.hand = 'RIGHT'; + var self = this; + + var timeSinceLastMoved = 0; + var RESET_TIME_THRESHOLD = 5; + var DISTANCE_FROM_HOME_THRESHOLD = 0.5; + var HOME_POSITION = { + x: 549.12, + y: 495.555, + z: 503.77 + }; + this.getUserData = function() { + + + if (this.properties.userData) { + this.userData = JSON.parse(this.properties.userData); + } } - this.setLeftHand = function() { - this.hand = 'LEFT'; + this.updateUserData = function() { + Entities.editEntity(this.entityId, { + userData: JSON.stringify(this.userData) + }); } - this.startNearGrab = function() { - this.whichHand = this.hand; - var position = Entities.getEntityProperties(this.entityId, "position").position; + this.update = function(deltaTime) { + self.getUserData(); + self.properties = Entities.getEntityProperties(self.entityId); + + if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { + timeSinceLastMoved += deltaTime; + if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { + self.reset(); + timeSinceLastMoved = 0; + } + } else { + timeSinceLastMoved = 0; + } + + //Only activate for the user who grabbed the object + if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { + if (self.activated !== true) { + //We were just grabbed, so create a particle system + self.grab(); + } + //Move emitter to where entity is always when its activated + self.sprayStream(); + } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { + self.letGo(); + } + } + + this.grab = function() { + this.activated = true; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -44,7 +85,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: position, + position: this.properties.position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", emitSpeed: 0, speedSpread: 0.02, @@ -59,33 +100,34 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); + } - this.sprayInjector = Audio.playSound(this.spraySound, { - position: position, - volume: 0.1 + this.letGo = function() { + this.activated = false; + Entities.deleteEntity(this.paintStream); + this.paintStream = null; + } + + this.reset = function() { + Entities.editEntity(self.entityId, { + position: HOME_POSITION, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + angularVelocity: ZERO_VEC, + velocity: ZERO_VEC }); } - - this.releaseGrab = function() { - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - this.painting = false; - this.sprayInjector.stop(); - } - - - this.continueNearGrab = function() { - var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); - var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + this.sprayStream = function() { + var forwardQuat = Quat.multiply(self.properties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)); + var forwardVec = Quat.getFront(self.properties.rotation); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(props.rotation); - var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + var upVec = Quat.getUp(self.properties.rotation); + var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(this.paintStream, { - position: position, - emitOrientation: forwardVec, + Entities.editEntity(self.paintStream, { + position: self.properties.position, + emitOrientation: self.properties.rotation, emitSpeed: 5 }); @@ -163,11 +205,31 @@ this.preload = function(entityId) { this.strokes = []; + this.activated = false; this.entityId = entityId; + this.properties = Entities.getEntityProperties(self.entityId); + this.getUserData(); + + //Only activate for the avatar who is grabbing the can! + if (this.userData.grabKey && this.userData.grabKey.activated) { + this.activated = true; + } + if (!this.userData.grabFrame) { + var data = { + relativePosition: { + x: 0, + y: 0, + z: 0 + }, + relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) + } + setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); + } } this.unload = function() { + Script.update.disconnect(this.update); if (this.paintStream) { Entities.deleteEntity(this.paintStream); } @@ -175,6 +237,7 @@ Entities.deleteEntity(stroke); }); } + Script.update.connect(this.update); }); @@ -185,4 +248,26 @@ function randFloat(min, max) { function randInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; +} + +function orientationOf(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); } \ No newline at end of file From 5da8b689c5a182d07c86a556daa89d0a43b557ae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:41:22 -0700 Subject: [PATCH 127/418] fix missing commas --- examples/toys/masterResetEntity.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index eebcefaaed..9eaa0e56d5 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -274,11 +274,11 @@ function createBlocks(position) { var i, j; var blockTypes = [ - { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} } - { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} } - { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} } - { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} } - { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} } + { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} }, + { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} }, + { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} }, + { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} }, + { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} }, ]; var modelURL, entity; From 83a8636a3668870ae6aecced4f0d7f6459fd8736 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 14:49:28 -0700 Subject: [PATCH 128/418] Remove whitespace, batch entity edits --- examples/toys/doll/createDoll.js | 19 +++++------- examples/toys/doll/doll.js | 51 ++++++++++++++++---------------- 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/examples/toys/doll/createDoll.js b/examples/toys/doll/createDoll.js index 8cb93a15df..ffd840f4ea 100644 --- a/examples/toys/doll/createDoll.js +++ b/examples/toys/doll/createDoll.js @@ -4,7 +4,6 @@ // Created by James B. Pollack @imgntn 9/23/2015 // Copyright 2015 High Fidelity, Inc. // -// ATTENTION: requires that you run handController.js // Creates a doll entity in front of you. // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -13,19 +12,15 @@ function createDoll() { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll.js"); - var center = Vec3.sum(Vec3.sum(MyAvatar.position, { - x: 0, - y: 0.5, - z: 0 - }), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); - var naturalDimensions = { - x: 1.63, - y: 1.67, - z: 0.26 - }; + var scriptURL = Script.resolvePath("doll.js"); + + var center = Vec3.sum(Vec3.sum(MyAvatar.position, { x: 0, y: 0.5, z: 0 }), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); + + var naturalDimensions = { x: 1.63, y: 1.67, z: 0.26}; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + var doll = Entities.addEntity({ type: "Model", name: "doll", diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 12a41d5e98..d47dd483ec 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -2,20 +2,22 @@ // // Script Type: Entity // Created by Eric Levin on 9/21/15. +// Additions by James B. Pollack @imgntn on 9/24/15 // Copyright 2015 High Fidelity, Inc. // -// ATTENTION: requires that you run handController.js // This entity script plays an animation and a sound while you hold it. // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +// Known issues: If you pass the doll between hands, animation can get into a weird state. We want to prevent the animation from starting again when you switch hands, but when you switch mid-animation your hand at release is still the first hand and not the current hand. /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -(function () { + +(function() { Script.include("../../utilities.js"); Script.include("../../libraries/utils.js"); // this is the "constructor" for the entity as a JS object we don't do much here - var Doll = function () { + var Doll = function() { this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; }; @@ -27,21 +29,20 @@ lastFrame: 128, startAutomatically: true }), - stopAnimationSetting: JSON.stringify({ - running: false, - }), + stopAnimationSetting: JSON.stringify({running: false}), audioInjector: null, isGrabbed: false, - setLeftHand: function () { + setLeftHand: function() { this.hand = 'left'; }, - setRightHand: function () { + setRightHand: function() { this.hand = 'right'; }, - startNearGrab: function () { + startNearGrab: function() { if (this.isGrabbed === false) { + Entities.editEntity(this.entityID, { animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting @@ -52,41 +53,41 @@ position: position, volume: 0.1 }); + this.isGrabbed = true; this.initialHand = this.hand; } }, - continueNearGrab: function () { - var position = Entities.getEntityProperties(this.entityID, "position").position; + continueNearGrab: function() { + var props = Entities.getEntityProperties(this.entityID, "position"); var audioOptions = { - position: position + position: props.position }; this.audioInjector.options = audioOptions; }, - releaseGrab: function () { - if (this.isGrabbed === true && this.hand === this.initialHand) { - this.audioInjector.stop(); - Entities.editEntity(this.entityID, { - animationSettings: this.stopAnimationSetting - }); + releaseGrab: function() { + if (this.isGrabbed === true && this.hand === this.initialHand) { + + this.audioInjector.stop(); + Entities.editEntity(this.entityID, { + animationSettings: this.stopAnimationSetting, animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); - this.isGrabbed = false; - } + this.isGrabbed = false; + } }, - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - preload: function (entityID) { + preload: function(entityID) { + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID this.entityID = entityID; }, }; - // entity scripts always need to return a newly constructed object of our type return new Doll(); }); \ No newline at end of file From 9eb3b56e5da5ee3eb4b04df4bfc3c54287f24b7e Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 15:03:02 -0700 Subject: [PATCH 129/418] Remove space before and after function calls, add spaces btw functions --- examples/controllers/handControllerGrab.js | 165 +++++++------------ examples/entityScripts/changeColorOnTouch.js | 38 ++--- 2 files changed, 82 insertions(+), 121 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index c6c1befda7..df7f67169c 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -2,6 +2,7 @@ // examples // // Created by Eric Levin on 9/2/15 +// Additions by James B. Pollack @imgntn on 9/24/2015 // Copyright 2015 High Fidelity, Inc. // // Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects. @@ -28,21 +29,9 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { - red: 10, - green: 10, - blue: 255 -}; // line color when pick misses -var INTERSECT_COLOR = { - red: 250, - green: 10, - blue: 10 -}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = { - x: 1000, - y: 1000, - z: 1000 -}; +var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255}; // line color when pick misses +var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000, z: 1000}; var LINE_LENGTH = 500; @@ -65,11 +54,7 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var RIGHT_HAND = 1; var LEFT_HAND = 0; -var ZERO_VEC = { - x: 0, - y: 0, - z: 0 -}; +var ZERO_VEC = { x: 0, y: 0, z: 0}; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; @@ -89,8 +74,7 @@ var STATE_RELEASE = 7; var GRAB_USER_DATA_KEY = "grabKey"; - -function controller(hand, triggerAction) { +function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; @@ -99,6 +83,7 @@ function controller(hand, triggerAction) { this.getHandPosition = MyAvatar.getLeftPalmPosition; this.getHandRotation = MyAvatar.getLeftPalmRotation; } + this.triggerAction = triggerAction; this.palm = 2 * hand; // this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed @@ -110,37 +95,38 @@ function controller(hand, triggerAction) { this.pointer = null; // entity-id of line object this.triggerValue = 0; // rolling average of trigger value var _this = this; - this.update = function () { + + this.update = function() { switch (this.state) { - case STATE_SEARCHING: - this.search(); - this.touchTest(); - break; - case STATE_DISTANCE_HOLDING: - this.distanceHolding(); - break; - case STATE_CONTINUE_DISTANCE_HOLDING: - this.continueDistanceHolding(); - break; - case STATE_NEAR_GRABBING: - this.nearGrabbing(); - break; - case STATE_CONTINUE_NEAR_GRABBING: - this.continueNearGrabbing(); - break; - case STATE_NEAR_GRABBING_NON_COLLIDING: - this.nearGrabbingNonColliding(); - break; - case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: - this.continueNearGrabbingNonColliding(); - break; - case STATE_RELEASE: - this.release(); - break; + case STATE_SEARCHING: + this.search(); + this.touchTest(); + break; + case STATE_DISTANCE_HOLDING: + this.distanceHolding(); + break; + case STATE_CONTINUE_DISTANCE_HOLDING: + this.continueDistanceHolding(); + break; + case STATE_NEAR_GRABBING: + this.nearGrabbing(); + break; + case STATE_CONTINUE_NEAR_GRABBING: + this.continueNearGrabbing(); + break; + case STATE_NEAR_GRABBING_NON_COLLIDING: + this.nearGrabbingNonColliding(); + break; + case STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING: + this.continueNearGrabbingNonColliding(); + break; + case STATE_RELEASE: + this.release(); + break; } }; - _this.pointerIDs = []; - this.lineOn = function (closePoint, farPoint, color) { + + this.lineOn = function(closePoint, farPoint, color) { // draw a line if (this.pointer === null) { this.pointer = Entities.addEntity({ @@ -153,7 +139,6 @@ function controller(hand, triggerAction) { color: color, lifetime: LIFETIME }); - _this.pointerIDs.push(this.pointer); } else { Entities.editEntity(this.pointer, { position: closePoint, @@ -165,20 +150,14 @@ function controller(hand, triggerAction) { }; - - this.lineOff = function () { + this.lineOff = function() { if (this.pointer !== null) { Entities.deleteEntity(this.pointer); } - var index = _this.pointerIDs.indexOf(this.pointer); - if (index > -1) { - _this.pointerIDs.splice(index, 1); - } this.pointer = null; }; - - this.triggerSmoothedSqueezed = function () { + this.triggerSmoothedSqueezed = function() { var triggerValue = Controller.getActionValue(this.triggerAction); // smooth out trigger value this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + @@ -186,16 +165,12 @@ function controller(hand, triggerAction) { return this.triggerValue > TRIGGER_ON_VALUE; }; - - this.triggerSqueezed = function () { + this.triggerSqueezed = function() { var triggerValue = Controller.getActionValue(this.triggerAction); return triggerValue > TRIGGER_ON_VALUE; }; - - this.search = function () { - - + this.search = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -248,8 +223,7 @@ function controller(hand, triggerAction) { }; - - this.distanceHolding = function () { + this.distanceHolding = function() { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); @@ -282,12 +256,9 @@ function controller(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); } - - }; - - this.continueDistanceHolding = function () { + this.continueDistanceHolding = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -319,9 +290,7 @@ function controller(hand, triggerAction) { this.currentObjectTime = now; // this doubles hand rotation - var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); + var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), Quat.inverse(this.handPreviousRotation)); this.handPreviousRotation = handRotation; this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); @@ -335,8 +304,7 @@ function controller(hand, triggerAction) { }); }; - - this.nearGrabbing = function () { + this.nearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -381,7 +349,7 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); }; - this.continueNearGrabbing = function () { + this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -400,7 +368,7 @@ function controller(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); }; - this.nearGrabbingNonColliding = function () { + this.nearGrabbingNonColliding = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -409,7 +377,7 @@ function controller(hand, triggerAction) { this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; }; - this.continueNearGrabbingNonColliding = function () { + this.continueNearGrabbingNonColliding = function() { if (!this.triggerSmoothedSqueezed()) { this.state = STATE_RELEASE; return; @@ -417,28 +385,28 @@ function controller(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; - _this.allTouchedIDs = {}; - this.touchTest = function () { - //print('touch test'); + this.touchTest = function() { var maxDistance = 0.05; var leftHandPosition = MyAvatar.getLeftPalmPosition(); var rightHandPosition = MyAvatar.getRightPalmPosition(); var leftEntities = Entities.findEntities(leftHandPosition, maxDistance); var rightEntities = Entities.findEntities(rightHandPosition, maxDistance); var ids = []; + if (leftEntities.length !== 0) { - leftEntities.forEach(function (entity) { + leftEntities.forEach(function(entity) { ids.push(entity); }); } + if (rightEntities.length !== 0) { - rightEntities.forEach(function (entity) { + rightEntities.forEach(function(entity) { ids.push(entity); }); } - ids.forEach(function (id) { + ids.forEach(function(id) { var props = Entities.getEntityProperties(id, ["boundingBox", "name"]); if (props.name === 'pointer') { @@ -471,23 +439,22 @@ function controller(hand, triggerAction) { }; - this.startTouch = function (entityID) { + this.startTouch = function(entityID) { // print('START TOUCH' + entityID); Entities.callEntityMethod(entityID, "startTouch"); }; - this.continueTouch = function (entityID) { + this.continueTouch = function(entityID) { // print('CONTINUE TOUCH' + entityID); Entities.callEntityMethod(entityID, "continueTouch"); }; - this.stopTouch = function (entityID) { + this.stopTouch = function(entityID) { // print('STOP TOUCH' + entityID); Entities.callEntityMethod(entityID, "stopTouch"); - }; - this.computeReleaseVelocity = function (deltaPosition, deltaTime, useMultiplier) { + this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) { if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) { var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime); // don't update grabbedVelocity if the trigger is off. the smoothing of the trigger @@ -504,8 +471,7 @@ function controller(hand, triggerAction) { } }; - - this.release = function () { + this.release = function() { this.lineOff(); if (this.grabbedEntity !== null && this.actionID !== null) { @@ -526,12 +492,11 @@ function controller(hand, triggerAction) { this.state = STATE_SEARCHING; }; - - this.cleanup = function () { + this.cleanup = function() { this.release(); }; - this.activateEntity = function () { + this.activateEntity = function() { var data = { activated: true, avatarId: MyAvatar.sessionUUID @@ -539,7 +504,7 @@ function controller(hand, triggerAction) { setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); }; - this.deactivateEntity = function () { + this.deactivateEntity = function() { var data = { activated: false, avatarId: null @@ -548,22 +513,18 @@ function controller(hand, triggerAction) { }; } - -var rightController = new controller(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); -var leftController = new controller(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); - +var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); +var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); function update() { rightController.update(); leftController.update(); } - function cleanup() { rightController.cleanup(); leftController.cleanup(); } - Script.scriptEnding.connect(cleanup); Script.update.connect(update); \ No newline at end of file diff --git a/examples/entityScripts/changeColorOnTouch.js b/examples/entityScripts/changeColorOnTouch.js index b3082fa9d5..3a8ebae956 100644 --- a/examples/entityScripts/changeColorOnTouch.js +++ b/examples/entityScripts/changeColorOnTouch.js @@ -13,54 +13,54 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ -(function () { - ChangeColorOnTouch = function () { + +(function() { + + function ChangeColorOnTouch () { this.oldColor = {}; this.oldColorKnown = false; - }; + } ChangeColorOnTouch.prototype = { - storeOldColor: function (entityID) { + storeOldColor: function(entityID) { var oldProperties = Entities.getEntityProperties(entityID); this.oldColor = oldProperties.color; this.oldColorKnown = true; + print("storing old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue); }, - preload: function (entityID) { + preload: function(entityID) { print("preload"); + this.entityID = entityID; this.storeOldColor(entityID); }, - startTouch: function () { + startTouch: function() { print("startTouch"); + if (!this.oldColorKnown) { this.storeOldColor(this.entityID); } - Entities.editEntity(this.entityID, { - color: { - red: 0, - green: 255, - blue: 255 - } - }); + + Entities.editEntity(this.entityID, {color: { red: 0, green: 255, blue: 255 }}); }, - continueTouch: function () { + continueTouch: function() { //unused here return; }, - stopTouch: function () { + stopTouch: function() { print("stopTouch"); + if (this.oldColorKnown) { print("leave restoring old color... this.oldColor=" + this.oldColor.red + "," + this.oldColor.green + "," + this.oldColor.blue); - Entities.editEntity(this.entityID, { - color: this.oldColor - }); + Entities.editEntity(this.entityID, {color: this.oldColor}); } } @@ -68,4 +68,4 @@ }; return new ChangeColorOnTouch(); -}) \ No newline at end of file +}); \ No newline at end of file From 629ee7b0c153faeb3a1f1101e956eeca9b1c3558 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 24 Sep 2015 15:12:10 -0700 Subject: [PATCH 130/418] Completely remove SOXR from cmake --- BUILD.md | 1 - cmake/externals/soxr/CMakeLists.txt | 34 --------------------- cmake/modules/FindSoxr.cmake | 43 --------------------------- libraries/audio-client/CMakeLists.txt | 7 +---- libraries/audio/CMakeLists.txt | 6 ---- 5 files changed, 1 insertion(+), 90 deletions(-) delete mode 100644 cmake/externals/soxr/CMakeLists.txt delete mode 100644 cmake/modules/FindSoxr.cmake diff --git a/BUILD.md b/BUILD.md index ae4a67c2ee..e2f310bb1f 100644 --- a/BUILD.md +++ b/BUILD.md @@ -13,7 +13,6 @@ * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.4 * [gverb](https://github.com/highfidelity/gverb) -* [Soxr](http://sourceforge.net/projects/soxr/) ~> 0.1.1 The following external projects are optional dependencies. You can indicate to CMake that you would like to include them by passing -DGET_$NAME=1 when running a clean CMake build. For example, to get CMake to download and compile SDL2 you would pass -DGET_SDL2=1. diff --git a/cmake/externals/soxr/CMakeLists.txt b/cmake/externals/soxr/CMakeLists.txt deleted file mode 100644 index 69d2276ab9..0000000000 --- a/cmake/externals/soxr/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -set(EXTERNAL_NAME soxr) - -if (ANDROID) - set(PLATFORM_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19" "-DHAVE_WORDS_BIGENDIAN_EXITCODE=1") -endif () - -include(ExternalProject) -ExternalProject_Add( - ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/soxr-0.1.1.zip - URL_MD5 349b5b2f323a7380bc12186d98c77d1d - CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DBUILD_SHARED_LIBS=1 -DBUILD_TESTS=0 -DCMAKE_INSTALL_PREFIX:PATH= - LOG_DOWNLOAD 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 - BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build -) - -# Hide this external target (for ide users) -set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") - -ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) - -string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE PATH "List of soxr include directories") - -if (WIN32) - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/soxr.lib CACHE FILEPATH "List of soxr libraries") - set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${INSTALL_DIR}/bin CACHE PATH "Path to soxr dll") -elseif (APPLE) - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libsoxr.dylib CACHE FILEPATH "List of soxr libraries") -else () - set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${INSTALL_DIR}/lib/libsoxr.so CACHE FILEPATH "List of soxr libraries") -endif () \ No newline at end of file diff --git a/cmake/modules/FindSoxr.cmake b/cmake/modules/FindSoxr.cmake deleted file mode 100644 index df6ad8050e..0000000000 --- a/cmake/modules/FindSoxr.cmake +++ /dev/null @@ -1,43 +0,0 @@ -# -# FindSoxr.cmake -# -# Try to find the libsoxr resampling library -# -# You can provide a LIBSOXR_ROOT_DIR which contains lib and include directories -# -# Once done this will define -# -# SOXR_FOUND - system found libsoxr -# SOXR_INCLUDE_DIRS - the libsoxr include directory -# SOXR_LIBRARIES - link to this to use libsoxr -# -# Created on 1/22/2015 by Stephen Birarda -# Copyright 2015 High Fidelity, Inc. -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") -hifi_library_search_hints("soxr") - -find_path(SOXR_INCLUDE_DIRS soxr.h PATH_SUFFIXES include HINTS ${SOXR_SEARCH_DIRS}) -find_library(SOXR_LIBRARIES NAMES soxr PATH_SUFFIXES lib HINTS ${SOXR_SEARCH_DIRS}) - -if (WIN32) - find_path(SOXR_DLL_PATH soxr.dll PATH_SUFFIXES bin HINTS ${SOXR_SEARCH_DIRS}) -endif() - -set(SOXR_REQUIREMENTS SOXR_INCLUDE_DIRS SOXR_LIBRARIES) -if (WIN32) - list(APPEND SOXR_REQUIREMENTS SOXR_DLL_PATH) -endif () - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Soxr DEFAULT_MSG ${SOXR_REQUIREMENTS}) - -if (WIN32) - add_paths_to_fixup_libs(${SOXR_DLL_PATH}) -endif () - -mark_as_advanced(SOXR_INCLUDE_DIRS SOXR_LIBRARIES SOXR_SEARCH_DIRS) \ No newline at end of file diff --git a/libraries/audio-client/CMakeLists.txt b/libraries/audio-client/CMakeLists.txt index 76f4cb4a0f..f631ec6387 100644 --- a/libraries/audio-client/CMakeLists.txt +++ b/libraries/audio-client/CMakeLists.txt @@ -9,18 +9,13 @@ link_hifi_libraries(audio) target_include_directories(${TARGET_NAME} PUBLIC "${HIFI_LIBRARY_DIR}/audio/src") # have CMake grab externals for us -add_dependency_external_projects(gverb soxr) +add_dependency_external_projects(gverb) find_package(Gverb REQUIRED) target_link_libraries(${TARGET_NAME} ${GVERB_LIBRARIES}) target_include_directories(${TARGET_NAME} PRIVATE ${GVERB_INCLUDE_DIRS}) -# we use libsoxr for resampling -find_package(Soxr REQUIRED) -target_link_libraries(${TARGET_NAME} ${SOXR_LIBRARIES}) -target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SOXR_INCLUDE_DIRS}) - if (APPLE) find_library(CoreAudio CoreAudio) find_library(CoreFoundation CoreFoundation) diff --git a/libraries/audio/CMakeLists.txt b/libraries/audio/CMakeLists.txt index c03f588d94..5134ccda36 100644 --- a/libraries/audio/CMakeLists.txt +++ b/libraries/audio/CMakeLists.txt @@ -7,10 +7,4 @@ add_dependency_external_projects(glm) find_package(GLM REQUIRED) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) -# we use libsoxr for resampling -add_dependency_external_projects(soxr) -find_package(Soxr REQUIRED) -target_link_libraries(${TARGET_NAME} ${SOXR_LIBRARIES}) -target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SOXR_INCLUDE_DIRS}) - link_hifi_libraries(networking shared) From 49d3b7e93bdd3dce9682560bb8825ba587ace3aa Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 15:26:19 -0700 Subject: [PATCH 131/418] fix indentation --- examples/toys/doll/doll.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index d47dd483ec..f97b6de378 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -56,7 +56,6 @@ this.isGrabbed = true; this.initialHand = this.hand; - } }, @@ -69,16 +68,16 @@ }, releaseGrab: function() { - if (this.isGrabbed === true && this.hand === this.initialHand) { + if (this.isGrabbed === true && this.hand === this.initialHand) { - this.audioInjector.stop(); + this.audioInjector.stop(); Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting, animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); - this.isGrabbed = false; - } + this.isGrabbed = false; + } }, preload: function(entityID) { From 8dacd736df9793e9352f7008844f4144e520eef6 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 15:27:26 -0700 Subject: [PATCH 132/418] fix weird multi line thing --- examples/controllers/handControllerGrab.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index df7f67169c..ce2f1b5249 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -272,9 +272,7 @@ function MyController(hand, triggerAction) { this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR); // the action was set up on a previous call. update the targets. - var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); + var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR); var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; From 266c69fc70712c304ed712f6eb932959e45940a6 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 24 Sep 2015 15:33:52 -0700 Subject: [PATCH 133/418] Disable the old-school Rig::inverseKinematics during reset. --- interface/src/avatar/MyAvatar.cpp | 2 ++ libraries/animation/src/Rig.cpp | 2 +- libraries/animation/src/Rig.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 1c3744c362..c704327d16 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -156,6 +156,7 @@ void MyAvatar::reset() { bool isRig = _rig->getEnableRig(); bool isGraph = _rig->getEnableAnimGraph(); qApp->setRawAvatarUpdateThreading(false); + _rig->disableHands = true; setEnableRigAnimations(true); _skeletonModel.simulate(0.1f); // non-zero setEnableRigAnimations(false); @@ -167,6 +168,7 @@ void MyAvatar::reset() { setEnableAnimGraph(true); Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true); } + _rig->disableHands = false; qApp->setRawAvatarUpdateThreading(); } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 770e857c4a..1874939b3d 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -738,7 +738,7 @@ void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::q return; } - if (_enableAnimGraph && _animSkeleton) { + if (disableHands || (_enableAnimGraph && _animSkeleton)) { // the hand data goes through a different path: Rig::updateFromHandParameters() --> early-exit return; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 37e1d51a0a..90082ca38b 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -193,6 +193,7 @@ public: AnimNode::ConstPointer getAnimNode() const { return _animNode; } AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; } + bool disableHands {false}; // should go away with rig animation (and Rig::inverseKinematics) protected: From ce0a726eb908f6864ee86f3bf8631664743b3f74 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 16:27:17 -0700 Subject: [PATCH 134/418] Fixed spraypaint for new particles --- examples/toys/sprayPaintCan.js | 138 ++++++++++----------------------- 1 file changed, 40 insertions(+), 98 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 8f3bb12307..0508cab038 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,11 +3,12 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; - var TIP_OFFSET_Z = 0.14; - var TIP_OFFSET_Y = 0.04; + this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); + + var TIP_OFFSET_Z = 0.02; + var TIP_OFFSET_Y = 0.08; var ZERO_VEC = { x: 0, @@ -19,59 +20,17 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } + this.setRightHand = function() { + this.hand = 'RIGHT'; } - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); + this.setLeftHand = function() { + this.hand = 'LEFT'; } - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; + this.startNearGrab = function() { + this.whichHand = this.hand; + var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -85,14 +44,15 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: this.properties.position, + position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitSpeed: 0, + emitSpeed: 3, speedSpread: 0.02, - polarFinish: 2 * DEG_TO_RAD, emitAcceleration: ZERO_VEC, emitRate: 100, particleRadius: 0.01, + radiusSpread: 0.005, + accelerationSpread: {x: 1, y: 1, x: 1}, color: { red: 170, green: 20, @@ -100,35 +60,38 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); - } - this.letGo = function() { - this.activated = false; - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - } - - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC + this.sprayInjector = Audio.playSound(this.spraySound, { + position: position, + volume: 0.1 }); } - this.sprayStream = function() { - var forwardQuat = Quat.multiply(self.properties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)); - var forwardVec = Quat.getFront(self.properties.rotation); + + this.releaseGrab = function() { + Entities.deleteEntity(this.paintStream); + this.paintStream = null; + this.painting = false; + this.sprayInjector.stop(); + } + + + this.continueNearGrab = function() { + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); + var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + + var forwardQuat = orientationOf(forwardVec); + + + var upVec = Quat.getUp(props.rotation); + var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { - position: self.properties.position, - emitOrientation: self.properties.rotation, - emitSpeed: 5 + Entities.editEntity(this.paintStream, { + position: position, + emitOrientation: forwardQuat, + // emitSpeed: 3 }); //Now check for an intersection with an entity @@ -205,31 +168,11 @@ this.preload = function(entityId) { this.strokes = []; - this.activated = false; this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } } this.unload = function() { - Script.update.disconnect(this.update); if (this.paintStream) { Entities.deleteEntity(this.paintStream); } @@ -237,7 +180,6 @@ Entities.deleteEntity(stroke); }); } - Script.update.connect(this.update); }); From be1952797c071c609dce76868ad82dd59010ae8d Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 16:31:59 -0700 Subject: [PATCH 135/418] Changes to rotations --- examples/toys/masterResetEntity.js | 82 +++++++++++++++++------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 901777be09..f674e3673d 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -76,6 +76,24 @@ function createAllToys() { //Handles toggling of all sconce lights createLightSwitches(); + + createArmChair({ + x: 549.39, + y: 494.57, + z: 508.37 + }) + + createPillow({ + x: 549.39, + y: 495.00, + z: 508.37 + }); + + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); } function deleteAllToys() { @@ -527,16 +545,11 @@ function createBlocks(position) { } } -//createPottedPlant,createArmChair,createPillow -function createPottedPlant() { +function createPottedPlant(position) { var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; - var position = { - x: 554.26, - y: 495.23, - z: 504.53 - } + var rotation = Quat.fromPitchYawRollDegress(0,0,0); var entity = Entities.addEntity({ type: "Model", @@ -544,7 +557,7 @@ function createPottedPlant() { modelURL: modelURL, position: position, dimensions: { - x: 1.10 + x: 1.10, y: 2.18, z: 1.07 }, @@ -568,34 +581,28 @@ function createPottedPlant() { }); }; -function createArmChair() { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair.fbx"; - var position = { - x: 549.39, - y: 494.57, - z: 508.37 - } - var ARM_CHAIR_COLLISION_SHAPE = ""; + +function createArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + +var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var entity = Entities.addEntity({ type: "Model", - name: "Arm Chair", + name: "Red Arm Chair", modelURL: modelURL, - shapeType:'compound', - compoundShapeURL: ARM_CHAIR_COLLISION_SHAPE, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, position: position, - rotation: { - x: 0, - y: -143.01, - z: 0 - }, + rotation:rotation, dimensions: { x: 1.26, y: 1.56, z: 1.35 }, collisionsWillMove: true, - shapeType: 'box', gravity: { x: 0, y: -9.8, @@ -605,7 +612,8 @@ function createArmChair() { x: 0, y: -0.1, z: 0 - } + }, + linearDamping: 0.4 }); setEntityCustomData(resetKey, entity, { @@ -613,25 +621,26 @@ function createArmChair() { }); }; -function createPillow() { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair_pillow.fbx"; - var position = { - x: 549.39, - y: 495.00, - z: 508.37 - } +function createPillow(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; + var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var entity = Entities.addEntity({ type: "Model", - name: "Arm Chair Pillow", + name: "Red Arm Chair Pillow", modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, position: position, + rotation:rotation, dimensions: { x: 0.07, y: 0.17, z: 0.07 }, collisionsWillMove: true, - shapeType: 'box', gravity: { x: 0, y: -9.8, @@ -641,7 +650,8 @@ function createPillow() { x: 0, y: -0.1, z: 0 - } + }, + linearDamping:0.4 }); setEntityCustomData(resetKey, entity, { From fd4395650226d85b78dac8ada86b4e0c52f37b6b Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 16:35:59 -0700 Subject: [PATCH 136/418] re add allTouchedIDs object --- examples/controllers/handControllerGrab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ce2f1b5249..a13f1de86d 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -383,6 +383,7 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; + _this.allTouchedIDs={}; this.touchTest = function() { var maxDistance = 0.05; var leftHandPosition = MyAvatar.getLeftPalmPosition(); From c2f1141d6915fc3cf998babb5d38af158f1d78b6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 16:40:20 -0700 Subject: [PATCH 137/418] fix cat script --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 98d08969a7..a71cec95c2 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -29,7 +29,7 @@ startTouch: function() { this.meow(); - } + }, meow: function() { From 85b2322accd73c40c1df7494dbd67b4e60de8f28 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 24 Sep 2015 17:11:14 -0700 Subject: [PATCH 138/418] more work on batch optimzation --- interface/src/Application.cpp | 163 ++++++++++-------- interface/src/ui/ApplicationCompositor.cpp | 4 +- interface/src/ui/ApplicationOverlay.cpp | 37 ++-- libraries/gpu/src/gpu/Context.h | 5 +- .../input-plugins/ViveControllerManager.cpp | 2 +- .../src/AmbientOcclusionEffect.cpp | 2 +- .../render-utils/src/AntialiasingEffect.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 6 +- libraries/render-utils/src/HitEffect.cpp | 2 +- libraries/render-utils/src/Model.cpp | 15 +- .../render-utils/src/RenderDeferredTask.cpp | 8 +- libraries/render/src/render/DrawStatus.cpp | 2 +- libraries/render/src/render/DrawTask.cpp | 2 +- 13 files changed, 138 insertions(+), 112 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c68cf1cd4d..13dcfe332e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1037,6 +1037,8 @@ void Application::initializeUi() { void Application::paintGL() { PROFILE_RANGE(__FUNCTION__); + PerformanceTimer perfTimer("paintGL"); + if (nullptr == _displayPlugin) { return; } @@ -1063,18 +1065,19 @@ void Application::paintGL() { lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - PerformanceTimer perfTimer("paintGL"); - - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::paintGL()"); resizeGL(); // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened - renderArgs._context->syncCache(); + { + PerformanceTimer perfTimer("syncCache"); + renderArgs._context->syncCache(); + } if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + PerformanceTimer perfTimer("Mirror"); auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; @@ -1088,7 +1091,7 @@ void Application::paintGL() { auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w); auto selfieFbo = DependencyManager::get()->getSelfieFramebuffer(); - doInBatch(renderArgs._context, [=](gpu::Batch& batch) { + gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) { batch.setFramebuffer(selfieFbo); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest); @@ -1106,81 +1109,86 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - _myAvatar->startCapture(); - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); - Application::getInstance()->cameraMenuChanged(); - } + { + PerformanceTimer perfTimer("CameraUpdates"); - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = _myAvatar->getSensorToWorldMatrix() * _myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setRotation(glm::quat_cast(camMat)); - } else { - _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); + _myAvatar->startCapture(); + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); + Application::getInstance()->cameraMenuChanged(); } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * hmdRotation); - // Ignore MenuOption::CenterPlayerInView in HMD view - glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + _myAvatar->getOrientation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f) + hmdOffset)); - } else { - _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + _myCamera.getRotation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = _myAvatar->getSensorToWorldMatrix() * _myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setRotation(glm::quat_cast(camMat)); } else { + _myCamera.setPosition(_myAvatar->getDefaultEyePosition()); + _myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation()); + } + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * hmdRotation); + // Ignore MenuOption::CenterPlayerInView in HMD view + glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + _myAvatar->getOrientation() - * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f) + hmdOffset)); + } else { + _myCamera.setRotation(_myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + _myCamera.getRotation() + * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } else { + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + _myAvatar->getOrientation() + * (_myAvatar->getScale() * _myAvatar->getBoomLength() * glm::vec3(0.0f, 0.0f, 1.0f))); + } } + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); + } else { + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)) * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(_myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))) * hmdOffset); - } else { - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(_myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) - + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _fps); } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + _myAvatar->endCapture(); } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _fps); - } - _myAvatar->endCapture(); // Primary rendering pass auto framebufferCache = DependencyManager::get(); const QSize size = framebufferCache->getFrameBufferSize(); { PROFILE_RANGE(__FUNCTION__ "/mainRender"); + PerformanceTimer perfTimer("mainRender"); // Viewport is assigned to the size of the framebuffer renderArgs._viewport = ivec4(0, 0, size.width(), size.height()); if (displayPlugin->isStereo()) { @@ -1217,7 +1225,7 @@ void Application::paintGL() { } displaySide(&renderArgs, _myCamera); renderArgs._context->enableStereo(false); - doInBatch(renderArgs._context, [](gpu::Batch& batch) { + gpu::doInBatch(renderArgs._context, [](gpu::Batch& batch) { batch.setFramebuffer(nullptr); }); } @@ -1225,6 +1233,7 @@ void Application::paintGL() { // Overlay Composition, needs to occur after screen space effects have completed { PROFILE_RANGE(__FUNCTION__ "/compositor"); + PerformanceTimer perfTimer("compositor"); auto primaryFbo = framebufferCache->getPrimaryFramebuffer(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo)); if (displayPlugin->isStereo()) { @@ -1249,6 +1258,7 @@ void Application::paintGL() { // deliver final composited scene to the display plugin { PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); + PerformanceTimer perfTimer("pluginOutput"); auto primaryFbo = framebufferCache->getPrimaryFramebuffer(); GLuint finalTexture = gpu::GLBackend::getTextureID(primaryFbo->getRenderBuffer(0)); // Ensure the rendering context commands are completed when rendering @@ -1266,24 +1276,29 @@ void Application::paintGL() { { PROFILE_RANGE(__FUNCTION__ "/pluginDisplay"); + PerformanceTimer perfTimer("pluginDisplay"); displayPlugin->display(finalTexture, toGlm(size)); } { PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); + PerformanceTimer perfTimer("bufferSwap"); displayPlugin->finishFrame(); } } - _offscreenContext->makeCurrent(); - _frameCount++; - Stats::getInstance()->setRenderDetails(renderArgs._details); + { + PerformanceTimer perfTimer("makeCurrent"); + _offscreenContext->makeCurrent(); + _frameCount++; + Stats::getInstance()->setRenderDetails(renderArgs._details); - // Reset the gpu::Context Stages - // Back to the default framebuffer; - doInBatch(renderArgs._context, [=](gpu::Batch& batch) { - batch.resetStages(); - }); + // Reset the gpu::Context Stages + // Back to the default framebuffer; + gpu::doInBatch(renderArgs._context, [=](gpu::Batch& batch) { + batch.resetStages(); + }); + } } void Application::runTests() { diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index ec93137d3a..497a94bb86 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -207,7 +207,7 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { updateTooltips(); //Handle fading and deactivation/activation of UI - doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { auto geometryCache = DependencyManager::get(); @@ -278,7 +278,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int auto geometryCache = DependencyManager::get(); - doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { geometryCache->useSimpleDrawPipeline(batch); batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 7254295c2f..03d6432104 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -70,29 +70,28 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { } // Execute the batch into our framebuffer - gpu::Batch batch; - renderArgs->_batch = &batch; + doInBatch(renderArgs->_context, [=](gpu::Batch& batch) { + renderArgs->_batch = &batch; - int width = _overlayFramebuffer->getWidth(); - int height = _overlayFramebuffer->getHeight(); + int width = _overlayFramebuffer->getWidth(); + int height = _overlayFramebuffer->getHeight(); - batch.setViewportTransform(glm::ivec4(0, 0, width, height)); - batch.setFramebuffer(_overlayFramebuffer); + batch.setViewportTransform(glm::ivec4(0, 0, width, height)); + batch.setFramebuffer(_overlayFramebuffer); - glm::vec4 color { 0.0f, 0.0f, 0.0f, 0.0f }; - float depth = 1.0f; - int stencil = 0; - batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, color, depth, stencil); + glm::vec4 color { 0.0f, 0.0f, 0.0f, 0.0f }; + float depth = 1.0f; + int stencil = 0; + batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, color, depth, stencil); - // Now render the overlay components together into a single texture - renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line - renderAudioScope(renderArgs); // audio scope in the very back - renderRearView(renderArgs); // renders the mirror view selfie - renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts - renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope - renderStatsAndLogs(renderArgs); // currently renders nothing - - renderArgs->_context->render(batch); + // Now render the overlay components together into a single texture + renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line + renderAudioScope(renderArgs); // audio scope in the very back + renderRearView(renderArgs); // renders the mirror view selfie + renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts + renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope + renderStatsAndLogs(renderArgs); // currently renders nothing + }); renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 286decfad4..ad21d71427 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -215,8 +215,6 @@ protected: }; typedef std::shared_ptr ContextPointer; -}; - template void doInBatch(std::shared_ptr context, F f) { static gpu::Batch::CacheState cacheState; @@ -226,4 +224,7 @@ void doInBatch(std::shared_ptr context, F f) { cacheState = batch.getCacheState(); } +}; + + #endif diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index 3d6f2e1656..bb8267b616 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -173,7 +173,7 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()]; UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()]; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { auto geometryCache = DependencyManager::get(); geometryCache->useSimpleDrawPipeline(batch); DependencyManager::get()->bindSimpleProgram(batch, true); diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 73c316648b..456a6430a7 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -179,7 +179,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { auto framebufferCache = DependencyManager::get(); QSize framebufferSize = framebufferCache->getFrameBufferSize(); float fbWidth = framebufferSize.width(); diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 9af3f90a4e..aaef67542f 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -101,7 +101,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re } RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); auto framebufferCache = DependencyManager::get(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5ace0d4e13..a9d83aa9d6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -340,7 +340,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu } void DeferredLightingEffect::prepare(RenderArgs* args) { - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); batch.setStateScissorRect(args->_viewport); @@ -357,7 +357,7 @@ void DeferredLightingEffect::prepare(RenderArgs* args) { gpu::FramebufferPointer _copyFBO; void DeferredLightingEffect::render(RenderArgs* args) { - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { // Allocate the parameters buffer used by all the deferred shaders if (!_deferredTransformBuffer[0]._buffer) { @@ -685,7 +685,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { void DeferredLightingEffect::copyBack(RenderArgs* args) { auto framebufferCache = DependencyManager::get(); - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.enableStereo(false); QSize framebufferSize = framebufferCache->getFrameBufferSize(); diff --git a/libraries/render-utils/src/HitEffect.cpp b/libraries/render-utils/src/HitEffect.cpp index b3915aa072..06bd07b456 100644 --- a/libraries/render-utils/src/HitEffect.cpp +++ b/libraries/render-utils/src/HitEffect.cpp @@ -63,7 +63,7 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende assert(renderContext->args); assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ff27c3ab62..7aee46b108 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1272,6 +1272,8 @@ void Model::simulateInternal(float deltaTime) { updateRig(deltaTime, parentTransform); } void Model::updateClusterMatrices() { + PerformanceTimer perfTimer("Model::updateClusterMatrices"); + if (!_needsUpdateClusterMatrices) { return; } @@ -1528,6 +1530,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape { if (!_showTrueJointTransforms) { + PerformanceTimer perfTimer("_rig->updateVisibleJointStates()"); _rig->updateVisibleJointStates(); } // else no need to update visible transforms } @@ -1692,6 +1695,8 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape // TODO: We should be able to do that just in the renderTransparentJob if (translucentMesh && locations->lightBufferUnit >= 0) { + PerformanceTimer perfTimer("DLE->setupTransparent()"); + DependencyManager::get()->setupTransparent(args, locations->lightBufferUnit); } @@ -1702,8 +1707,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape } } - batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); - batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + { + PerformanceTimer perfTimer("batch.drawIndexed()"); + batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); + batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + } if (args) { const int INDICES_PER_TRIANGLE = 3; @@ -1743,6 +1751,9 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, Locations*& locations) { + PerformanceTimer perfTimer("Model::pickPrograms"); + + RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe); if (mode == RenderArgs::MIRROR_RENDER_MODE) { key = RenderKey(key.getRaw() | RenderKey::IS_MIRROR); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 35ac2e4af2..65f77689c3 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -32,7 +32,7 @@ using namespace render; void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); @@ -166,7 +166,7 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; @@ -195,7 +195,7 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const assert(renderContext->args->_viewFrustum); RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); args->_batch = &batch; @@ -267,7 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon } // Render the items - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 66067f3ff2..32cd21d0bc 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -126,7 +126,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex } // Allright, something to render let's do it - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { glm::mat4 projMat; Transform viewMat; args->_viewFrustum->evalProjectionMatrix(projMat); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 644b9b0adf..e2c4c5f747 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -236,7 +236,7 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext cullItems(sceneContext, renderContext, inItems, culledItems); RenderArgs* args = renderContext->args; - doInBatch(args->_context, [=](gpu::Batch& batch) { + gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; renderItems(sceneContext, renderContext, culledItems); }); From baf47777506a89f2f55c252db7788070b80b8727 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 17:13:45 -0700 Subject: [PATCH 139/418] Can now hold spray paint can without painting unless squeezing hard --- examples/toys/masterResetEntity.js | 2 +- examples/toys/sprayPaintCan.js | 83 +++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b7bfc708e3..a2f6c9f233 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -26,7 +26,7 @@ createAllToys(); function createAllToys() { createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); - createSprayCan({ x: 549.8, y: 495.6, z: 503.94 }); + createSprayCan({ x: 549.7, y: 495.6, z: 503.91 }); createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 0508cab038..945dc4322f 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,7 +3,6 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - this.userData = {}; this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); @@ -16,6 +15,9 @@ z: 0 } + // if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray + var DISABLE_SPRAY_THRESHOLD = 0.7; + var MAX_POINTS_PER_LINE = 40; var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; @@ -30,6 +32,24 @@ this.startNearGrab = function() { this.whichHand = this.hand; + } + + this.toggleWithTriggerPressure = function() { + var handClickString = this.whichHand + "_HAND_CLICK"; + + var handClick = Controller.findAction(handClickString); + + this.triggerValue = Controller.getActionValue(handClick); + if (this.triggerValue < DISABLE_SPRAY_THRESHOLD && this.spraying === true) { + this.spraying = false; + this.disableStream(); + } else if (this.triggerValue >= DISABLE_SPRAY_THRESHOLD && this.spraying === false) { + this.spraying = true; + this.enableStream(); + } + } + + this.enableStream = function() { var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, @@ -43,6 +63,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", + name: "streamEffect", animationSettings: animationSettings, position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", @@ -52,7 +73,6 @@ emitRate: 100, particleRadius: 0.01, radiusSpread: 0.005, - accelerationSpread: {x: 1, y: 1, x: 1}, color: { red: 170, green: 20, @@ -61,14 +81,23 @@ lifetime: 50, //probably wont be holding longer than this straight }); + setEntityCustomData(this.resetKey, this.paintStream, { + resetMe: true + }); + this.sprayInjector = Audio.playSound(this.spraySound, { position: position, volume: 0.1 }); + } - this.releaseGrab = function() { + this.disableStream(); + } + + this.disableStream = function() { + print("DEKETE STEREAAAM") Entities.deleteEntity(this.paintStream); this.paintStream = null; this.painting = false; @@ -77,21 +106,23 @@ this.continueNearGrab = function() { + + this.toggleWithTriggerPressure(); + + if (this.spraying === false) { + return; + } + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - - var forwardQuat = orientationOf(forwardVec); - - var upVec = Quat.getUp(props.rotation); var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) Entities.editEntity(this.paintStream, { position: position, emitOrientation: forwardQuat, - // emitSpeed: 3 }); //Now check for an intersection with an entity @@ -168,7 +199,9 @@ this.preload = function(entityId) { this.strokes = []; + this.spraying = false; this.entityId = entityId; + this.resetKey = "resetMe"; } @@ -193,23 +226,23 @@ function randInt(min, max) { } function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; - var theta = 0.0; + var theta = 0.0; - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); } \ No newline at end of file From 20d784ba39dbefc5e3521f1a7aaea3b7b506bb66 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 24 Sep 2015 17:54:32 -0700 Subject: [PATCH 140/418] Threshold based walking while in HMD. This is a blend of the previous 'sitting' and 'standing' HMD modes. Basically, when you move your head within a small range (20cm) your avatar will lean appropriately, however when you cross that threshold your body will move underneath you, re-centering your head above the body. While this occurs the avatar should play the appropriate walking animations. --- .../defaultAvatar_full/avatar-animation.json | 4 +- interface/src/Application.cpp | 6 +- interface/src/Menu.cpp | 3 - interface/src/avatar/Head.cpp | 16 ++-- interface/src/avatar/MyAvatar.cpp | 74 ++++++++++++------- interface/src/avatar/MyAvatar.h | 9 +-- interface/src/avatar/SkeletonModel.cpp | 2 +- interface/src/ui/OverlayConductor.cpp | 6 +- 8 files changed, 64 insertions(+), 56 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 550a95e980..03c5a103ff 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -559,7 +559,7 @@ "id": "strafeLeft", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/strafe_left.fbx", + "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_left.fbx", "startFrame": 0.0, "endFrame": 31.0, "timeScale": 1.0, @@ -571,7 +571,7 @@ "id": "strafeRight", "type": "clip", "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/strafe_right.fbx", + "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/standard_anims/side_step_right.fbx", "startFrame": 0.0, "endFrame": 31.0, "timeScale": 1.0, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c68cf1cd4d..e41a375144 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -708,7 +708,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // Now that menu is initalized we can sync myAvatar with it's state. _myAvatar->updateMotionBehaviorFromMenu(); - _myAvatar->updateStandingHMDModeFromMenu(); // the 3Dconnexion device wants to be initiliazed after a window is displayed. ConnexionClient::getInstance().init(); @@ -1053,8 +1052,6 @@ void Application::paintGL() { auto displayPlugin = getActiveDisplayPlugin(); displayPlugin->preRender(); _offscreenContext->makeCurrent(); - // update the avatar with a fresh HMD pose - _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose()); auto lodManager = DependencyManager::get(); @@ -2883,6 +2880,9 @@ void Application::update(float deltaTime) { userInputMapper->getActionState(UserInputMapper::SHIFT), RIGHT_HAND_INDEX); } + // update the avatar with a fresh HMD pose + _myAvatar->updateFromHMDSensorMatrix(getHMDSensorPose(), deltaTime); + updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateCamera(deltaTime); // handle various camera tweaks like off axis projection diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index bd5287c256..5793510fb5 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -294,9 +294,6 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::TurnWithHead, 0, false); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::StandingHMDSensorMode, 0, false, - avatar, SLOT(updateStandingHMDModeFromMenu())); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::WorldAxes); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 96c55dfa93..d9a1b190d6 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -124,14 +124,12 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { _isEyeTrackerConnected = eyeTracker->isTracking(); } - if (!myAvatar->getStandingHMDSensorMode()) { - // Twist the upper body to follow the rotation of the head, but only do this with my avatar, - // since everyone else will see the full joint rotations for other people. - const float BODY_FOLLOW_HEAD_YAW_RATE = 0.1f; - const float BODY_FOLLOW_HEAD_FACTOR = 0.66f; - float currentTwist = getTorsoTwist(); - setTorsoTwist(currentTwist + (getFinalYaw() * BODY_FOLLOW_HEAD_FACTOR - currentTwist) * BODY_FOLLOW_HEAD_YAW_RATE); - } + // Twist the upper body to follow the rotation of the head, but only do this with my avatar, + // since everyone else will see the full joint rotations for other people. + const float BODY_FOLLOW_HEAD_YAW_RATE = 0.1f; + const float BODY_FOLLOW_HEAD_FACTOR = 0.66f; + float currentTwist = getTorsoTwist(); + setTorsoTwist(currentTwist + (getFinalYaw() * BODY_FOLLOW_HEAD_FACTOR - currentTwist) * BODY_FOLLOW_HEAD_YAW_RATE); } if (!(_isFaceTrackerConnected || billboard)) { @@ -392,7 +390,7 @@ glm::quat Head::getCameraOrientation() const { // always the same. if (qApp->getAvatarUpdater()->isHMDMode()) { MyAvatar* myAvatar = dynamic_cast(_owningAvatar); - if (myAvatar && myAvatar->getStandingHMDSensorMode()) { + if (myAvatar) { return glm::quat_cast(myAvatar->getSensorToWorldMatrix()) * myAvatar->getHMDSensorOrientation(); } else { return getOrientation(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c499f9f5bb..12da9b4070 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -104,7 +104,6 @@ MyAvatar::MyAvatar(RigPointer rig) : _hmdSensorPosition(), _bodySensorMatrix(), _sensorToWorldMatrix(), - _standingHMDSensorMode(false), _goToPending(false), _goToPosition(), _goToOrientation(), @@ -249,26 +248,54 @@ void MyAvatar::simulate(float deltaTime) { } glm::mat4 MyAvatar::getSensorToWorldMatrix() const { - if (getStandingHMDSensorMode()) { - return _sensorToWorldMatrix; - } else { - return createMatFromQuatAndPos(getWorldAlignedOrientation(), getDefaultEyePosition()); - } + return _sensorToWorldMatrix; } // best called at start of main loop just after we have a fresh hmd pose. // update internal body position from new hmd pose. -void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { +void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float deltaTime) { // update the sensorMatrices based on the new hmd pose _hmdSensorMatrix = hmdSensorMatrix; _hmdSensorPosition = extractTranslation(hmdSensorMatrix); _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); - _bodySensorMatrix = deriveBodyFromHMDSensor(); - if (getStandingHMDSensorMode()) { - // set the body position/orientation to reflect motion due to the head. - auto worldMat = _sensorToWorldMatrix * _bodySensorMatrix; - nextAttitude(extractTranslation(worldMat), glm::quat_cast(worldMat)); + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); + glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); + if (!_straightingLean && glm::length(diff) > 0.2f) { + + // begin homing toward derived body position. + _straightingLean = true; + _straightingLeanAlpha = 0.0f; + + } else if (_straightingLean) { + + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); + auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix; + glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); + glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); + + const float STRAIGHTING_LEAN_DURATION = 0.5f; + _straightingLeanAlpha += (1.0f / STRAIGHTING_LEAN_DURATION) * deltaTime; + + if (_straightingLeanAlpha >= 1.0f) { + _straightingLean = false; + nextAttitude(worldBodyPos, worldBodyRot); + _bodySensorMatrix = newBodySensorMatrix; + } else { + // interp position toward the desired pos + glm::vec3 pos = lerp(getPosition(), worldBodyPos, _straightingLeanAlpha); + glm::quat rot = glm::normalize(safeMix(getOrientation(), worldBodyRot, _straightingLeanAlpha)); + nextAttitude(pos, rot); + + // interp sensor matrix toward desired + glm::vec3 nextBodyPos = extractTranslation(newBodySensorMatrix); + glm::quat nextBodyRot = glm::normalize(glm::quat_cast(newBodySensorMatrix)); + glm::vec3 prevBodyPos = extractTranslation(_bodySensorMatrix); + glm::quat prevBodyRot = glm::normalize(glm::quat_cast(_bodySensorMatrix)); + pos = lerp(prevBodyPos, nextBodyPos, _straightingLeanAlpha); + rot = glm::normalize(safeMix(prevBodyRot, nextBodyRot, _straightingLeanAlpha)); + _bodySensorMatrix = createMatFromQuatAndPos(rot, pos); + } } } @@ -340,11 +367,9 @@ void MyAvatar::updateFromTrackers(float deltaTime) { Head* head = getHead(); if (inHmd || isPlaying()) { - if (!getStandingHMDSensorMode()) { - head->setDeltaPitch(estimatedRotation.x); - head->setDeltaYaw(estimatedRotation.y); - head->setDeltaRoll(estimatedRotation.z); - } + head->setDeltaPitch(estimatedRotation.x); + head->setDeltaYaw(estimatedRotation.y); + head->setDeltaRoll(estimatedRotation.z); } else { float magnifyFieldOfView = qApp->getFieldOfView() / _realWorldFieldOfView.get(); @@ -366,12 +391,10 @@ void MyAvatar::updateFromTrackers(float deltaTime) { relativePosition.x = -relativePosition.x; } - if (!(inHmd && getStandingHMDSensorMode())) { - head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), - -MAX_LEAN, MAX_LEAN)); - head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), - -MAX_LEAN, MAX_LEAN)); - } + head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), + -MAX_LEAN, MAX_LEAN)); + head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), + -MAX_LEAN, MAX_LEAN)); } @@ -1725,11 +1748,6 @@ void MyAvatar::updateMotionBehaviorFromMenu() { _characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController)); } -void MyAvatar::updateStandingHMDModeFromMenu() { - Menu* menu = Menu::getInstance(); - _standingHMDSensorMode = menu->isOptionChecked(MenuOption::StandingHMDSensorMode); -} - //Renders sixense laser pointers for UI selection with controllers void MyAvatar::renderLaserPointers(gpu::Batch& batch) { const float PALM_TIP_ROD_RADIUS = 0.002f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c58ca235f3..c1a6ada751 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -68,7 +68,7 @@ public: // best called at start of main loop just after we have a fresh hmd pose. // update internal body position from new hmd pose. - void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); + void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float deltaTime); // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. @@ -168,7 +168,6 @@ public: static const float ZOOM_MAX; static const float ZOOM_DEFAULT; - bool getStandingHMDSensorMode() const { return _standingHMDSensorMode; } void doUpdateBillboard(); void destroyAnimGraph(); @@ -194,7 +193,6 @@ public slots: void setThrust(glm::vec3 newThrust) { _thrust = newThrust; } void updateMotionBehaviorFromMenu(); - void updateStandingHMDModeFromMenu(); glm::vec3 getLeftPalmPosition(); glm::vec3 getLeftPalmVelocity(); @@ -345,8 +343,6 @@ private: // used to transform any sensor into world space, including the _hmdSensorMat, or hand controllers. glm::mat4 _sensorToWorldMatrix; - bool _standingHMDSensorMode; - bool _goToPending; glm::vec3 _goToPosition; glm::quat _goToOrientation; @@ -362,6 +358,9 @@ private: AudioListenerMode _audioListenerMode; glm::vec3 _customListenPosition; glm::quat _customListenOrientation; + + bool _straightingLean = false; + float _straightingLeanAlpha = 0.0f; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index c248b54dc7..703f3983ee 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -123,7 +123,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { Rig::HeadParameters headParams; headParams.modelRotation = getRotation(); headParams.modelTranslation = getTranslation(); - headParams.enableLean = qApp->getAvatarUpdater()->isHMDMode() && !myAvatar->getStandingHMDSensorMode(); + headParams.enableLean = qApp->getAvatarUpdater()->isHMDMode(); headParams.leanSideways = head->getFinalLeanSideways(); headParams.leanForward = head->getFinalLeanForward(); headParams.torsoTwist = head->getTorsoTwist(); diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 21165b8c20..2e7838872a 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -69,11 +69,7 @@ void OverlayConductor::updateMode() { Mode newMode; if (qApp->isHMDMode()) { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - if (myAvatar->getStandingHMDSensorMode()) { - newMode = STANDING; - } else { - newMode = SITTING; - } + newMode = SITTING; } else { newMode = FLAT; } From 474c847ef1da4538f99afd707c4a826ec66b91d8 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 24 Sep 2015 18:00:59 -0700 Subject: [PATCH 141/418] Updated constants and units. --- interface/src/avatar/MyAvatar.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 12da9b4070..8e517991c0 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -259,9 +259,12 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float _hmdSensorPosition = extractTranslation(hmdSensorMatrix); _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); + const float STRAIGHTING_LEAN_DURATION = 0.5f; // seconds + const float STRAIGHTING_LEAN_THRESHOLD = 0.2f; // meters + auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straightingLean && glm::length(diff) > 0.2f) { + if (!_straightingLean && glm::length(diff) > STRAIGHTING_LEAN_THRESHOLD) { // begin homing toward derived body position. _straightingLean = true; @@ -274,7 +277,6 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix); glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix)); - const float STRAIGHTING_LEAN_DURATION = 0.5f; _straightingLeanAlpha += (1.0f / STRAIGHTING_LEAN_DURATION) * deltaTime; if (_straightingLeanAlpha >= 1.0f) { @@ -298,7 +300,7 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix, float } } } - +// // best called at end of main loop, just before rendering. // update sensor to world matrix from current body position and hmd sensor. // This is so the correct camera can be used for rendering. From 337bdfdaf6c07afea435baa5d2bd28467346151f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 18:35:26 -0700 Subject: [PATCH 142/418] end of day --- examples/toys/masterResetEntity.js | 47 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index f674e3673d..25e97829ad 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -78,15 +78,15 @@ function createAllToys() { createLightSwitches(); createArmChair({ - x: 549.39, - y: 494.57, - z: 508.37 + x: 549.29, + y: 495.05, + z: 508.22 }) createPillow({ - x: 549.39, - y: 495.00, - z: 508.37 + x: 549.29, + y: 495.25, + z: 508.22 }); createPottedPlant({ @@ -99,7 +99,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function (entity) { + entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -547,9 +547,9 @@ function createBlocks(position) { function createPottedPlant(position) { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegress(0,0,0); + var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); var entity = Entities.addEntity({ type: "Model", @@ -570,7 +570,7 @@ function createPottedPlant(position) { }, velocity: { x: 0, - y: -0.1, + y: 0, z: 0 }, linearDamping: 0.4 @@ -587,7 +587,7 @@ function createArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" -var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); var entity = Entities.addEntity({ type: "Model", @@ -596,7 +596,7 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); shapeType: 'compound', compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, position: position, - rotation:rotation, + rotation: rotation, dimensions: { x: 1.26, y: 1.56, @@ -605,15 +605,15 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); collisionsWillMove: true, gravity: { x: 0, - y: -9.8, + y: -0.5, z: 0 }, velocity: { x: 0, - y: -0.1, + y: 0, z: 0 }, - linearDamping: 0.4 + linearDamping: 0.3 }); setEntityCustomData(resetKey, entity, { @@ -624,8 +624,8 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); function createPillow(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + + var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); var entity = Entities.addEntity({ type: "Model", @@ -634,16 +634,17 @@ function createPillow(position) { shapeType: 'compound', compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, position: position, - rotation:rotation, + rotation: rotation, dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 + x: 0.4, + y: 0.4, + z: 0.4 }, collisionsWillMove: true, + ignoreForCollisions: false, gravity: { x: 0, - y: -9.8, + y: -10.1, z: 0 }, velocity: { @@ -651,7 +652,7 @@ function createPillow(position) { y: -0.1, z: 0 }, - linearDamping:0.4 + linearDamping: 1 }); setEntityCustomData(resetKey, entity, { From d063f3488d6aacc84e21edfc0668df0c0146edf6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 24 Sep 2015 19:14:26 -0700 Subject: [PATCH 143/418] Back out fromSpherical code addition --- libraries/script-engine/src/Vec3.cpp | 24 ++++++++++++++++++++++++ libraries/script-engine/src/Vec3.h | 4 ++-- libraries/shared/src/GLMHelpers.cpp | 24 ------------------------ libraries/shared/src/GLMHelpers.h | 4 ---- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/libraries/script-engine/src/Vec3.cpp b/libraries/script-engine/src/Vec3.cpp index 04e3a4fe05..88d6373b6d 100644 --- a/libraries/script-engine/src/Vec3.cpp +++ b/libraries/script-engine/src/Vec3.cpp @@ -58,3 +58,27 @@ glm::vec3 Vec3::toPolar(const glm::vec3& v) { return glm::vec3(elevation, azimuth, radius); } + +glm::vec3 Vec3::fromPolar(const glm::vec3& polar) { + float x = glm::cos(polar.x) * glm::sin(polar.y); + float y = glm::sin(-polar.x); + float z = glm::cos(polar.x) * glm::cos(polar.y); + + // Round small values to 0 + if (glm::abs(x) < EPSILON) { + x = 0.0f; + } + if (glm::abs(y) < EPSILON) { + y = 0.0f; + } + if (glm::abs(z) < EPSILON) { + z = 0.0f; + } + + return polar.z * glm::vec3(x, y, z); +} + +glm::vec3 Vec3::fromPolar(float elevation, float azimuth) { + glm::vec3 v = glm::vec3(elevation, azimuth, 1.0f); + return fromPolar(v); +} diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 2d703ac87e..b05e729a49 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -43,8 +43,8 @@ public slots: bool withinEpsilon(const glm::vec3& v1, const glm::vec3& v2, float epsilon); // FIXME misnamed, should be 'spherical' or 'euler' depending on the implementation glm::vec3 toPolar(const glm::vec3& v); - glm::vec3 fromPolar(const glm::vec3& polar) { return fromSpherical(polar); } - glm::vec3 fromPolar(float elevation, float azimuth) { return fromSpherical(elevation, azimuth); } + glm::vec3 fromPolar(const glm::vec3& polar); + glm::vec3 fromPolar(float elevation, float azimuth); const glm::vec3& UNIT_X() { return Vectors::UNIT_X; } const glm::vec3& UNIT_Y() { return Vectors::UNIT_Y; } const glm::vec3& UNIT_Z() { return Vectors::UNIT_Z; } diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 3d705cf99e..7d56157e53 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -225,30 +225,6 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) { return glm::angleAxis(angle, axis); } -glm::vec3 fromSpherical(const glm::vec3& spherical) { - float x = glm::cos(spherical.x) * glm::sin(spherical.y); - float y = glm::sin(-spherical.x); - float z = glm::cos(spherical.x) * glm::cos(spherical.y); - - // Round small values to 0 - if (glm::abs(x) < EPSILON) { - x = 0.0f; - } - if (glm::abs(y) < EPSILON) { - y = 0.0f; - } - if (glm::abs(z) < EPSILON) { - z = 0.0f; - } - - return spherical.z * glm::vec3(x, y, z); -} - -glm::vec3 fromSpherical(float elevation, float azimuth) { - glm::vec3 v = glm::vec3(elevation, azimuth, 1.0f); - return fromSpherical(v); -} - bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) { glm::vec3 v1 = p0 - p1, v2 = p2 - p1; // Non-collinear vectors contained in the plane glm::vec3 n = glm::cross(v1, v2); // Plane's normal vector, pointing out of the triangle diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 0245ca926f..6683088306 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -117,10 +117,6 @@ float angleBetween(const glm::vec3& v1, const glm::vec3& v2); glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2); -glm::vec3 fromSpherical(const glm::vec3& spherical); - -glm::vec3 fromSpherical(float elevation, float azimuth); - bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2); glm::vec3 extractTranslation(const glm::mat4& matrix); From 629128c17f3d191c1e98352a49b7eb85fb27eb97 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 24 Sep 2015 19:16:28 -0700 Subject: [PATCH 144/418] Fix particle emit directions for point emitter --- libraries/entities/src/ParticleEffectEntityItem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 8c45c860fa..3f3bde7077 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -711,10 +711,10 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { if (_emitDimensions == glm::vec3()) { // Point - emitDirection = _emitOrientation * fromSpherical(elevation, azimuth); + emitDirection = glm::angleAxis(PI_OVER_TWO - elevation, X_AXIS) * Z_AXIS; + emitDirection = glm::angleAxis(azimuth, Z_AXIS) * emitDirection; _particlePositions[i] = getPosition(); - } else { // Ellipsoid float radiusScale = 1.0f; From d233d3f81bdae9873cc93be0c5024398eb76e094 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 24 Sep 2015 19:17:02 -0700 Subject: [PATCH 145/418] Fix particle emitter corner cases --- libraries/entities/src/ParticleEffectEntityItem.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 3f3bde7077..9d11dff55a 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -682,9 +682,9 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } updateRadius(i, 0.0f); - // Velocity and acceleration - if (_polarStart == 0.0f && _polarFinish == 0.0f) { - // Emit along z-axis + // Position, velocity, and acceleration + if (_polarStart == 0.0f && _polarFinish == 0.0f && _emitDimensions.z == 0.0f) { + // Emit along z-axis from position _particlePositions[i] = getPosition(); _particleVelocities[i] = (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); @@ -730,9 +730,9 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { float z = radiuses.z * glm::sin(elevation); glm::vec3 emitPosition = glm::vec3(x, y, z); emitDirection = glm::normalize(glm::vec3( - x / (radiuses.x * radiuses.x), - y / (radiuses.y * radiuses.y), - z / (radiuses.z * radiuses.z) + radiuses.x > 0.0f ? x / (radiuses.x * radiuses.x) : 0.0f, + radiuses.y > 0.0f ? y / (radiuses.y * radiuses.y) : 0.0f, + radiuses.z > 0.0f ? z / (radiuses.z * radiuses.z) : 0.0f )); _particlePositions[i] = getPosition() + _emitOrientation * emitPosition; From 1051416ed7b0927a877edb65300c94d433a9cc1f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Fri, 25 Sep 2015 10:33:16 -0700 Subject: [PATCH 146/418] Change stat collection to batch stats together to make fewer network calls --- examples/example/misc/collectHifiStats.js | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 examples/example/misc/collectHifiStats.js diff --git a/examples/example/misc/collectHifiStats.js b/examples/example/misc/collectHifiStats.js new file mode 100644 index 0000000000..3902622217 --- /dev/null +++ b/examples/example/misc/collectHifiStats.js @@ -0,0 +1,93 @@ +// +// collectHifiStats.js +// +// Created by Thijs Wenker on 24 Sept 2015 +// Additions by James B. Pollack @imgntn on 25 Sept 2015 +// Copyright 2015 High Fidelity, Inc. +// +// Collects stats for analysis to a REST endpoint. Defaults to batching stats, but can be customized. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// The url where the data will be posted. +var ENDPOINT_URL = ""; + +var BATCH_STATS = true; +var BATCH_SIZE = 5; + +var batch = []; + +if (BATCH_STATS) { + + var RECORD_EVERY = 1000; // 1 seconds + var batchCount = 0; + + Script.setInterval(function() { + + if (batchCount === BATCH_SIZE) { + sendBatchToEndpoint(batch); + batchCount = 0; + } + Stats.forceUpdateStats(); + batch.push(getBatchStats()); + batchCount++; + }, RECORD_EVERY); + + +} else { + // Send the data every: + var SEND_EVERY = 30000; // 30 seconds + + Script.setInterval(function() { + Stats.forceUpdateStats(); + var req = new XMLHttpRequest(); + req.open("POST", ENDPOINT_URL, false); + req.send(getStats()); + }, SEND_EVERY); +} + +function getStats() { + return JSON.stringify({ + username: GlobalServices.username, + location: Window.location.hostname, + framerate: Stats.framerate, + simrate: Stats.simrate, + ping: { + audio: Stats.audioPing, + avatar: Stats.avatarPing, + entities: Stats.entitiesPing, + asset: Stats.assetPing + }, + position: Camera.position, + yaw: Stats.yaw, + rotation: Camera.orientation.x + ',' + Camera.orientation.y + ',' + Camera.orientation.z + ',' + Camera.orientation.w + }) +} + +function getBatchStats() { + // print('GET BATCH STATS'); + return { + username: GlobalServices.username, + location: Window.location.hostname, + framerate: Stats.framerate, + simrate: Stats.simrate, + ping: { + audio: Stats.audioPing, + avatar: Stats.avatarPing, + entities: Stats.entitiesPing, + asset: Stats.assetPing + }, + position: Camera.position, + yaw: Stats.yaw, + rotation: Camera.orientation.x + ',' + Camera.orientation.y + ',' + Camera.orientation.z + ',' + Camera.orientation.w + } +} + +function sendBatchToEndpoint(batch) { + // print('SEND BATCH TO ENDPOINT'); + var req = new XMLHttpRequest(); + req.open("POST", ENDPOINT_URL, false); + req.send(JSON.stringify(batch)); +} \ No newline at end of file From 0815b8e939138402fed27ffbcdd0325e0d7ce63b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 10:59:20 -0700 Subject: [PATCH 147/418] Added polar finish to spray paint stream --- examples/toys/sprayPaintCan.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 945dc4322f..0cce03de89 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -73,6 +73,7 @@ emitRate: 100, particleRadius: 0.01, radiusSpread: 0.005, + polarFinish: 0.1, color: { red: 170, green: 20, From f4007584e120ff880a40479555e3aba15e9a2269 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:02:41 -0700 Subject: [PATCH 148/418] formatted master script --- examples/toys/masterResetEntity.js | 339 +++++++++++++++++++++++------ 1 file changed, 278 insertions(+), 61 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index a2f6c9f233..b65d13a911 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -24,24 +24,54 @@ deleteAllToys(); createAllToys(); function createAllToys() { - createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); - createSprayCan({ x: 549.7, y: 495.6, z: 503.91 }); + createSprayCan({ + x: 549.7, + y: 495.6, + z: 503.91 + }); - createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); + createBasketBall({ + x: 547.73, + y: 495.5, + z: 505.47 + }); - createDoll({x: 546.67, y: 495.41, z: 505.09}); + createDoll({ + x: 546.67, + y: 495.41, + z: 505.09 + }); - createWand({ x: 546.71, y: 495.55, z: 506.15}); + createWand({ + x: 546.71, + y: 495.55, + z: 506.15 + }); createDice(); - createFlashlight({ x: 545.72, y: 495.41, z: 505.78 + createFlashlight({ + x: 545.72, + y: 495.41, + z: 505.78 }); - createCat({ x: 551.49859619140625, y: 495.49111938476562, z: 502.26498413085938 }); + createCat({ + x: 551.49859619140625, + y: 495.49111938476562, + z: 502.26498413085938 + }); - createMagballs({ x: 548.73, y: 495.51, z: 503.54 + createMagballs({ + x: 548.73, + y: 495.51, + z: 503.54 }); //Handles toggling of all sconce lights @@ -51,7 +81,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function (entity) { + entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -69,21 +99,36 @@ function createMagballs(position) { modelURL: modelURL, name: "Tin Can", position: position, - rotation: { w: 0.93041884899139404, x: -1.52587890625e-05, y: 0.36647593975067139, z: -1.52587890625e-05}, - dimensions: { x: 0.16946873068809509, y: 0.21260403096675873, z: 0.16946862637996674 }, + rotation: { + w: 0.93041884899139404, + x: -1.52587890625e-05, + y: 0.36647593975067139, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.16946873068809509, + y: 0.21260403096675873, + z: 0.16946862637996674 + }, }); - setEntityCustomData(resetKey, tinCan, { resetMe: true }); + setEntityCustomData(resetKey, tinCan, { + resetMe: true + }); - setEntityCustomData("OmniTool", tinCan, { script: "../toys/magBalls.js"}); + setEntityCustomData("OmniTool", tinCan, { + script: "../toys/magBalls.js" + }); } function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({running: true,}); + var animationSettings = JSON.stringify({ + running: true, + }); var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -92,11 +137,22 @@ function createCat(position) { animationURL: animationURL, animationSettings: animationSettings, position: position, - rotation: { w: 0.35020983219146729, x: -4.57763671875e-05, y: 0.93664455413818359, z: -1.52587890625e-05}, - dimensions: { x: 0.15723302960395813, y: 0.50762706995010376, z: 0.90716040134429932}, + rotation: { + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, }); - setEntityCustomData(resetKey, cat, { resetMe: true }); + setEntityCustomData(resetKey, cat, { + resetMe: true + }); } function createFlashlight(position) { @@ -109,14 +165,28 @@ function createFlashlight(position) { name: "flashlight", script: scriptURL, position: position, - dimensions: { x: 0.08, y: 0.30, z: 0.08}, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, collisionsWillMove: true, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: { x: 0, y: -0.01, z: 0}, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, shapeType: 'box', }); - setEntityCustomData(resetKey, flashlight, {resetMe: true}); + setEntityCustomData(resetKey, flashlight, { + resetMe: true + }); } @@ -129,9 +199,22 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: {x: 543.27764892578125, y: 495.67999267578125, z: 511.00564575195312}, - rotation: {w: 0.63280689716339111, x: 0.63280689716339111, y: -0.31551080942153931, z: 0.31548023223876953}, - dimensions: {x: 0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } }); setEntityCustomData(resetKey, lightSwitchHall, { @@ -145,12 +228,27 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Garage", script: scriptURL, - position: {x: 545.62, y: 495.68,z: 500.21}, - rotation: { w: 0.20082402229309082, x: 0.20082402229309082, y: -0.67800414562225342, z: 0.67797362804412842}, - dimensions: { x:0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } }); - setEntityCustomData(resetKey, lightSwitchGarage, {resetMe: true}); + setEntityCustomData(resetKey, lightSwitchGarage, { + resetMe: true + }); } @@ -160,22 +258,46 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541, y: 494.96, z: 509.1}, - dimensions: {x: 0.09, y: 0.09, z: 0.09}, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: {x: 0,y: -0.01, z: 0}, + position: { + x: 541, + y: 494.96, + z: 509.1 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, shapeType: "box", collisionsWillMove: true }; var dice1 = Entities.addEntity(diceProps); - diceProps.position = { x: 541.05, y: 494.96, z: 509.0 }; + diceProps.position = { + x: 541.05, + y: 494.96, + z: 509.0 + }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, {resetMe: true}); + setEntityCustomData(resetKey, dice1, { + resetMe: true + }); - setEntityCustomData(resetKey, dice2, {resetMe: true}); + setEntityCustomData(resetKey, dice2, { + resetMe: true + }); } function createWand(position) { @@ -189,8 +311,16 @@ function createWand(position) { type: "Model", modelURL: WAND_MODEL, position: position, - gravity: {x: 0, y: 0, z: 0}, - dimensions: { x: 0.05, y: 0.25,z: 0.05}, + gravity: { + x: 0, + y: 0, + z: 0 + }, + dimensions: { + x: 0.05, + y: 0.25, + z: 0.05 + }, //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, @@ -200,7 +330,9 @@ function createWand(position) { script: scriptURL }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createBasketBall(position) { @@ -214,22 +346,40 @@ function createBasketBall(position) { collisionsWillMove: true, shapeType: "sphere", name: "basketball", - dimensions: {x: 0.25, y: 0.26, z: 0.25}, - gravity: {x: 0, y: -7, z: 0}, + dimensions: { + x: 0.25, + y: 0.26, + z: 0.25 + }, + gravity: { + x: 0, + y: -7, + z: 0 + }, restitution: 10, linearDamping: 0.0, - velocity: { x: 0, y: -0.01, z: 0}, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var scriptURL = Script.resolvePath("doll/doll.js"); - var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -239,12 +389,22 @@ function createDoll(position) { position: position, shapeType: 'box', dimensions: desiredDimensions, - gravity: {x: 0, y: -5, z: 0}, - velocity: {x: 0, y: -0.1, z: 0}, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createSprayCan(position) { @@ -256,15 +416,29 @@ function createSprayCan(position) { name: "spraycan", modelURL: modelURL, position: position, - dimensions: {x: 0.07, y: 0.17, z: 0.07}, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, collisionsWillMove: true, shapeType: 'box', script: scriptURL, - gravity: {x: 0, y: -0.5, z: 0}, - velocity: { x: 0, y: -1, z: 0} + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: -1, + z: 0 + } }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } @@ -273,13 +447,42 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; var i, j; - var blockTypes = [ - { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} }, - { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} }, - { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} }, - { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} }, - { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} }, - ]; + var blockTypes = [{ + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }, ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -288,17 +491,31 @@ function createBlocks(position) { entity = Entities.addEntity({ type: "Model", modelURL: modelURL, - position: Vec3.sum(position, { x: j / 10, y: i / 10, z: 0}), + position: Vec3.sum(position, { + x: j / 10, + y: i / 10, + z: 0 + }), shapeType: 'box', name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, - gravity: {x: 0, y: -2.5, z: 0}, - velocity: { x: 0, y: -0.01, z: 0} + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + } }); //customKey, id, data - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } } } From a62970136282a22d062468660d4f9c17c716991f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:15:19 -0700 Subject: [PATCH 149/418] couch --- examples/toys/masterResetEntity.js | 134 +++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b65d13a911..d039bfbb6e 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -74,6 +74,24 @@ function createAllToys() { z: 503.54 }); + createArmChair({ + x: 549.29, + y: 495.05, + z: 508.22 + }) + + createPillow({ + x: 549.29, + y: 495.35, + z: 508.22 + }); + + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); + //Handles toggling of all sconce lights createLightSwitches(); } @@ -442,6 +460,122 @@ function createSprayCan(position) { } +//createPottedPlant,createArmChair,createPillow +function createPottedPlant(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; + + var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10, + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.4 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + + + +function createArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.3 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createPillow(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; + var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair Pillow", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 0.4, + y: 0.4, + z: 0.4 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + gravity: { + x: 0, + y: -10.1, + z: 0 + }, + restitution: 0, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + linearDamping: 1 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; var NUM_BLOCKS_PER_COLOR = 4; From d29c337e9549a7feb299ab288aadee3e5abd289a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:32:41 -0700 Subject: [PATCH 150/418] moved light switches up --- examples/toys/masterResetEntity.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index d039bfbb6e..b5f08a75d5 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -68,6 +68,9 @@ function createAllToys() { z: 502.26498413085938 }); + //Handles toggling of all sconce lights + createLightSwitches(); + createMagballs({ x: 548.73, y: 495.51, @@ -92,8 +95,7 @@ function createAllToys() { z: 504.53 }); - //Handles toggling of all sconce lights - createLightSwitches(); + } function deleteAllToys() { From 7789d8b3a8c77761c2b8a3f4f0a30adb43144de7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:37:04 -0700 Subject: [PATCH 151/418] fixed potted plant bug --- examples/toys/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b5f08a75d5..3ee991ea4c 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -466,7 +466,7 @@ function createSprayCan(position) { function createPottedPlant(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); var entity = Entities.addEntity({ type: "Model", From ccc6a343fcd0a72842de07ce3095a5e8c230da7d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:49:51 -0700 Subject: [PATCH 152/418] updated lights to use newly named grab events --- examples/controllers/handControllerGrab.js | 1 + examples/toys/lightSwitchGarage.js | 2 +- examples/toys/lightSwitchHall.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ce2f1b5249..09b73e6808 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -371,6 +371,7 @@ function MyController(hand, triggerAction) { this.state = STATE_RELEASE; return; } + print("JAYKJAGHKJAHKJAHKJAHKJ") Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding"); this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; }; diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 99d827aa06..5f302ff47e 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function() { + startNearGrabNonColliding: function() { this.toggleLights(); }, diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 49ccc51b79..4dd1a867de 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function() { + startNearGrabNonColliding: function() { this.toggleLights(); }, From 65169da64d042a8e4540bebdaf8936f937ba6ca5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:58:05 -0700 Subject: [PATCH 153/418] removed old doll script --- examples/toys/doll.js | 73 ------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 examples/toys/doll.js diff --git a/examples/toys/doll.js b/examples/toys/doll.js deleted file mode 100644 index 708d6200b1..0000000000 --- a/examples/toys/doll.js +++ /dev/null @@ -1,73 +0,0 @@ -// -// doll.js -// examples/toybox/entityScripts -// -// Created by Eric Levin on 9/21/15. -// Copyright 2015 High Fidelity, Inc. -// -// This entity script breathes movement and sound- one might even say life- into a doll. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - - var _this; - HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - Doll = function() { - _this = this; - var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; - this.startAnimationSetting = JSON.stringify({ - running: true, - startFrame: 0, - lastFrame: 128 - }); - - this.stopAnimationSetting = JSON.stringify({ - running: false, - }); - }; - - Doll.prototype = { - - - startNearGrab: function() { - Entities.editEntity(this.entityID, { - animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", - animationSettings: this.startAnimationSetting - }); - - var position = Entities.getEntityProperties(this.entityID, "position").position; - Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { - position: position, - volume: 0.1 - }); - - }, - - releaseGrab: function() { - Entities.editEntity(this.entityID, { - animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - // animationSettings: this.stopAnimationSetting, - // animationFrameIndex: 0 - }); - }, - - - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - // * connecting to the update signal so we can check our grabbed state - preload: function(entityID) { - this.entityID = entityID; - }, - }; - - // entity scripts always need to return a newly constructed object of our type - return new Doll(); -}) From f5e44675bb8493e54ffb9744918647066c8271b3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 12:11:22 -0700 Subject: [PATCH 154/418] removed start and end frame --- examples/toys/doll/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index f97b6de378..09dd06a2ec 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,8 +25,8 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - startFrame: 0, - lastFrame: 128, + // startFrame: 0, + // lastFrame: 128, startAutomatically: true }), stopAnimationSetting: JSON.stringify({running: false}), From c53ad3c5340e3821cbd070ff3ffacedf40d7dd82 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 12:34:35 -0700 Subject: [PATCH 155/418] combined arm chair --- examples/toys/doll/doll.js | 9 ++++-- examples/toys/masterResetEntity.js | 51 ++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 09dd06a2ec..62eac78166 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,11 +25,14 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - // startFrame: 0, - // lastFrame: 128, + firstFrame: 0, + lastFrame: 120, startAutomatically: true }), - stopAnimationSetting: JSON.stringify({running: false}), + stopAnimationSetting: JSON.stringify({ + running: false, + frameIndex: 0 + }), audioInjector: null, isGrabbed: false, setLeftHand: function() { diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 3ee991ea4c..2e7f9bdae3 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -77,17 +77,17 @@ function createAllToys() { z: 503.54 }); - createArmChair({ + createCombinedArmChair({ x: 549.29, y: 495.05, z: 508.22 }) - createPillow({ - x: 549.29, - y: 495.35, - z: 508.22 - }); + // createPillow({ + // x: 549.29, + // y: 495.35, + // z: 508.22 + // }); createPottedPlant({ x: 554.26, @@ -393,7 +393,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js"); + var scriptURL = Script.resolvePath("doll/doll.js?v2"+ Math.random()); var naturalDimensions = { x: 1.63, @@ -499,6 +499,43 @@ function createPottedPlant(position) { }; +function createCombinedArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.2 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; function createArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; From 402573dbf15d193a42b67735611ff9304203e900 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 25 Sep 2015 14:11:33 -0700 Subject: [PATCH 156/418] Remove unused local --- interface/src/ui/OverlayConductor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 2e7838872a..6e4d7e8248 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -68,7 +68,6 @@ void OverlayConductor::updateMode() { Mode newMode; if (qApp->isHMDMode()) { - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); newMode = SITTING; } else { newMode = FLAT; From a97f5569584371878752c8a18f5dfbcbd4e2da58 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 25 Sep 2015 15:13:57 -0700 Subject: [PATCH 157/418] enforce IK target rotation --- .../animation/src/AnimInverseKinematics.cpp | 66 +++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 7f32d8a2fa..de226092f1 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -9,6 +9,7 @@ #include "AnimInverseKinematics.h" +#include #include #include #include @@ -159,24 +160,34 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(tipIndex); + glm::quat tipParentRotation; + if (pivotIndex != -1) { + tipParentRotation = absolutePoses[pivotIndex].rot; + } // descend toward root, pivoting each joint to get tip closer to target - int pivotIndex = _skeleton->getParentIndex(tipIndex); - float fractionDenominator = 1.0f; + int ancestorCount = 1; while (pivotIndex != -1) { // compute the two lines that should be aligned glm::vec3 jointPosition = absolutePoses[pivotIndex].trans; - glm::vec3 leverArm = tip - jointPosition; + glm::vec3 leverArm = tipPosition - jointPosition; glm::vec3 targetLine = targetPose.trans - jointPosition; - // compute the axis of the rotation that would align them + // compute the swing that would get get tip closer glm::vec3 axis = glm::cross(leverArm, targetLine); float axisLength = glm::length(axis); glm::quat deltaRotation; const float MIN_AXIS_LENGTH = 1.0e-4f; if (axisLength > MIN_AXIS_LENGTH) { - // compute deltaRotation for alignment (brings tip closer to target) + // compute deltaRotation for alignment (swings tip closer to target) axis /= axisLength; float angle = acosf(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine))); @@ -184,24 +195,50 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector MIN_ADJUSTMENT_ANGLE) { - // reduce angle by half: slows convergence but adds stability to IK solution - angle /= fractionDenominator; + // reduce angle by a fraction (reduces IK swing contribution of this joint) + angle /= (float)ancestorCount; deltaRotation = glm::angleAxis(angle, axis); } + + // The swing will re-orient the tip but there will tend to be be a non-zero delta between the tip's + // new rotation and its target. We compute that delta here and rotate the tipJoint accordingly. + glm::quat tipRelativeRotation = glm::inverse(deltaRotation * tipParentRotation) * targetPose.rot; + + // enforce tip's constraint + RotationConstraint* constraint = getConstraint(tipIndex); + if (constraint) { + bool constrained = constraint->apply(tipRelativeRotation); + if (constrained) { + // The tip's final parent-relative rotation violates its constraint + // so we try to twist this pivot to compensate. + glm::quat constrainedTipRotation = deltaRotation * tipParentRotation * tipRelativeRotation; + glm::quat missingRotation = targetPose.rot * glm::inverse(constrainedTipRotation); + glm::quat swingPart; + glm::quat twistPart; + glm::vec3 axis = glm::normalize(deltaRotation * leverArm); + swingTwistDecomposition(missingRotation, axis, swingPart, twistPart); + deltaRotation = twistPart * deltaRotation; + } + // we update the tip rotation here to rotate it as close to its target orientation as possible + // before moving on to next pivot + tipRotation = tipParentRotation * tipRelativeRotation; + } } - fractionDenominator++; + ++ancestorCount; int parentIndex = _skeleton->getParentIndex(pivotIndex); if (parentIndex == -1) { // TODO? apply constraints to root? // TODO? harvest the root's transform as movement of entire skeleton? } else { - // compute joint's new parent-relative rotation + // compute joint's new parent-relative rotation after swing // Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q glm::quat newRot = glm::normalize(glm::inverse( absolutePoses[parentIndex].rot) * deltaRotation * absolutePoses[pivotIndex].rot); + + // enforce pivot's constraint RotationConstraint* constraint = getConstraint(pivotIndex); if (constraint) { bool constrained = constraint->apply(newRot); @@ -214,6 +251,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(pivotIndex); } @@ -464,7 +504,7 @@ void AnimInverseKinematics::initConstraints() { } else if (0 == baseName.compare("Hand", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); - const float MAX_HAND_TWIST = PI; + const float MAX_HAND_TWIST = 3.0f * PI / 5.0f; const float MIN_HAND_TWIST = -PI / 2.0f; if (isLeft) { stConstraint->setTwistLimits(-MAX_HAND_TWIST, -MIN_HAND_TWIST); From 1f7914766c7ddaef4dcbe898c1f1d885c07c05dc Mon Sep 17 00:00:00 2001 From: James Pollack Date: Fri, 25 Sep 2015 15:26:29 -0700 Subject: [PATCH 158/418] Add ability to prevent an object from being grabbable by specifying a custom key grabbableKey to grabbable:false --- examples/controllers/handControllerGrab.js | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index a13f1de86d..27ffbee60c 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -72,8 +72,9 @@ var STATE_NEAR_GRABBING_NON_COLLIDING = 5; var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 6; var STATE_RELEASE = 7; - var GRAB_USER_DATA_KEY = "grabKey"; +var GRABBABLE_DATA_KEY = "grabbableKey"; + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -182,6 +183,11 @@ function MyController(hand, triggerAction) { origin: handPosition, direction: Quat.getUp(this.getHandRotation()) }; + + var defaultGrabbableData = { + grabbable: true + }; + var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && @@ -190,9 +196,15 @@ function MyController(hand, triggerAction) { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); this.grabbedEntity = intersection.entityID; + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, defaultGrabbableData); + if (grabbableData.grabbable === false) { + return; + } if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { // the hand is very close to the intersected object. go into close-grabbing mode. this.state = STATE_NEAR_GRABBING; + } else { // the hand is far from the intersected object. go into distance-holding mode this.state = STATE_DISTANCE_HOLDING; @@ -203,8 +215,16 @@ function MyController(hand, triggerAction) { var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var minDistance = GRAB_RADIUS; var i, props, distance; + for (i = 0; i < nearbyEntities.length; i++) { + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], defaultGrabbableData); + if (grabbableData.grabbable === false) { + return + } + props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); + distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; @@ -383,7 +403,7 @@ function MyController(hand, triggerAction) { Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; - _this.allTouchedIDs={}; + _this.allTouchedIDs = {}; this.touchTest = function() { var maxDistance = 0.05; var leftHandPosition = MyAvatar.getLeftPalmPosition(); From e94d9b39fdb0413a405cd7f2524f2e079316f625 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 15:42:13 -0700 Subject: [PATCH 159/418] made pots and chair not grabbable --- examples/toys/doll/doll.js | 12 ++++++------ examples/toys/masterResetEntity.js | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 62eac78166..e81f3e0c0e 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,13 +25,12 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - firstFrame: 0, - lastFrame: 120, - startAutomatically: true + // firstFrame: 1, + // lastFrame: 120, }), stopAnimationSetting: JSON.stringify({ running: false, - frameIndex: 0 + frameIndex: 1 }), audioInjector: null, isGrabbed: false, @@ -74,10 +73,11 @@ if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); - + print("STTTOP ANIMATION") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting, - animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + animationIsPlaying: false + // animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); this.isGrabbed = false; } diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 2e7f9bdae3..88a71cd58e 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -13,6 +13,7 @@ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); var resetKey = "resetMe"; +var GRABBABLE_DATA_KEY = "grabbableKey"; var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; @@ -68,7 +69,7 @@ function createAllToys() { z: 502.26498413085938 }); - //Handles toggling of all sconce lights + //Handles toggling of all sconce lights createLightSwitches(); createMagballs({ @@ -393,7 +394,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js?v2"+ Math.random()); + var scriptURL = Script.resolvePath("doll/doll.js?v2" + Math.random()); var naturalDimensions = { x: 1.63, @@ -496,6 +497,11 @@ function createPottedPlant(position) { setEntityCustomData(resetKey, entity, { resetMe: true }); + + + setEntityCustomData(GRABBABLE_DATA_KEY, entity, { + grabbable: false + }); }; @@ -535,6 +541,10 @@ function createCombinedArmChair(position) { setEntityCustomData(resetKey, entity, { resetMe: true }); + + setEntityCustomData(GRABBABLE_DATA_KEY, entity, { + grabbable: false + }); }; function createArmChair(position) { From 534cffcf85d83ab1880701812dfe64e5d2f24b8d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 16:23:35 -0700 Subject: [PATCH 160/418] fixed animation bug with doll --- examples/toys/doll/doll.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index e81f3e0c0e..f0b789273c 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,12 +25,14 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - // firstFrame: 1, - // lastFrame: 120, + loop: false, + firstFrame: 1, + lastFrame: 120, }), stopAnimationSetting: JSON.stringify({ running: false, - frameIndex: 1 + frameIndex: 1, + lastFrame: 10000 }), audioInjector: null, isGrabbed: false, @@ -73,13 +75,14 @@ if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); - print("STTTOP ANIMATION") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting, - animationIsPlaying: false - // animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + animationIsPlaying: false, + animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); this.isGrabbed = false; + + var frameIndex = Entities.getEntityProperties(this.entityID, {}) } }, From bcd21714910d5f115692964120a4e99557c039fa Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 16:28:12 -0700 Subject: [PATCH 161/418] updated chair model --- examples/toys/masterResetEntity.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 88a71cd58e..5a8732e348 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -548,8 +548,8 @@ function createCombinedArmChair(position) { }; function createArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair_collision_hull.obj" var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); From 14fc39ffa3426764de43f34e6564348a8f912242 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 26 Sep 2015 02:36:01 +0200 Subject: [PATCH 162/418] Added JS access to the variables Stats.audioPacketlossUpstream Stats.audioPacketlossDownstream Which contain a floating point with the value between 0.0f and 1.0f which is the percentage of packet loss. --- interface/src/ui/Stats.cpp | 1 + interface/src/ui/Stats.h | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ebce4f2b96..831664e3e6 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -46,6 +46,7 @@ Stats::Stats(QQuickItem* parent) : QQuickItem(parent) { INSTANCE = this; const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); _monospaceFont = font.family(); + _audioStats = &DependencyManager::get()->getStats(); } bool Stats::includeTimingRecord(const QString& name) { diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 2e4c5e4dca..d6aa255dc6 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -12,6 +12,7 @@ #include #include #include +#include #define STATS_PROPERTY(type, name, initialValue) \ Q_PROPERTY(type name READ name NOTIFY name##Changed) \ @@ -27,6 +28,8 @@ class Stats : public QQuickItem { Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged) Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT) + Q_PROPERTY(float audioPacketlossUpstream READ getAudioPacketLossUpstream) + Q_PROPERTY(float audioPacketlossDownstream READ getAudioPacketLossDownstream) STATS_PROPERTY(int, serverCount, 0) STATS_PROPERTY(int, framerate, 0) @@ -81,6 +84,10 @@ public: const QString& monospaceFont() { return _monospaceFont; } + + float getAudioPacketLossUpstream() { return _audioStats->getMixerAvatarStreamStats()._packetStreamStats.getLostRate(); } + float getAudioPacketLossDownstream() { return _audioStats->getMixerDownstreamStats()._packetStreamStats.getLostRate(); } + void updateStats(bool force = false); bool isExpanded() { return _expanded; } @@ -149,6 +156,7 @@ private: bool _expanded{ false }; bool _timingExpanded{ false }; QString _monospaceFont; + const AudioIOStats* _audioStats; }; #endif // hifi_Stats_h From 8f25e54027bfaf9e858b4d131a546b839809189a Mon Sep 17 00:00:00 2001 From: James Pollack Date: Fri, 25 Sep 2015 18:34:34 -0700 Subject: [PATCH 163/418] Hoop, ball, ground --- examples/toys/basketball/createHoop.js | 101 +++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 examples/toys/basketball/createHoop.js diff --git a/examples/toys/basketball/createHoop.js b/examples/toys/basketball/createHoop.js new file mode 100644 index 0000000000..778c73915c --- /dev/null +++ b/examples/toys/basketball/createHoop.js @@ -0,0 +1,101 @@ +// +// createFlashlight.js +// examples/entityScripts +// +// Created by Sam Gateau on 9/9/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is a toy script that create a flashlight entity that lit when grabbed +// This can be run from an interface and the flashlight will get deleted from the domain when quitting +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +/*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +Script.include("../../utilities.js"); +Script.include("../../libraries/utils.js"); + +var groundURL = "https://hifi-public.s3.amazonaws.com/eric/models/woodFloor.fbx"; +var basketballURL = "https://hifi-public.s3.amazonaws.com/models/content/basketball2.fbx"; +var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_hoop_2.fbx"; +var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball/new_basketball_hoop_collision_hull.obj"; +var ballCollisionSound = "https://hifi-public.s3.amazonaws.com/sounds/basketball/basketball.wav"; + +var basePosition = { + x: 0, + y: 0, + z: 0 +}; + +var hoopStartPosition = { + x: 0, + y: 3.25, + z: 0 +}; + + +var ground = Entities.addEntity({ + type: "Model", + modelURL: groundURL, + dimensions: { + x: 100, + y: 2, + z: 100 + }, + position: basePosition, + shapeType: 'box' +}); + +var BALL_DIAMETER = 0.30; +var DISTANCE_IN_FRONT_OF_ME = 1.0; + +var ballPosition = Vec3.sum(MyAvatar.position, + Vec3.multiplyQbyV(MyAvatar.orientation, { + x: 0, + y: 0.0, + z: -DISTANCE_IN_FRONT_OF_ME + })); + +var ballRotation = Quat.multiply(MyAvatar.orientation, + Quat.fromPitchYawRollDegrees(0, -90, 0)); + +var basketball = Entities.addEntity({ + type: "Model", + position: ballPosition, + rotation: ballRotation, + dimensions: { + x: BALL_DIAMETER, + y: BALL_DIAMETER, + z: BALL_DIAMETER + }, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + collisionsWillMove: true, + collisionSoundURL: ballCollisionSound, + modelURL: basketballURL, + restitution: 1.0, + linearDamping: 0.00001, + shapeType: "sphere" +}); + + +var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: hoopStartPosition, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL +}); \ No newline at end of file From 4a1458e152518947674fd86c2492655cf01638b5 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 25 Sep 2015 19:05:55 -0700 Subject: [PATCH 164/418] Algorithmic optimization of new resampler. All common sample rates now use a rational mode that does direct FIR filtering instead of coefficient interpolation. Complexity reduced by 2x for mono, 1.5x for stereo. --- libraries/audio/src/AudioSRC.cpp | 264 +++++++++++++++++++++++++------ libraries/audio/src/AudioSRC.h | 7 +- 2 files changed, 218 insertions(+), 53 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index c8ef2f8800..e909e870e7 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -74,7 +74,7 @@ static void* aligned_malloc(size_t size, size_t alignment) { return ptr; } } - return NULL; + return nullptr; } static void aligned_free(void* ptr) { @@ -84,6 +84,19 @@ static void aligned_free(void* ptr) { } } +// find the greatest common divisor +static int gcd(int a, int b) +{ + while (a != b) { + if (a > b) { + a -= b; + } else { + b -= a; + } + } + return a; +} + // // 3rd-order Lagrange interpolation // @@ -91,8 +104,9 @@ static void aligned_free(void* ptr) { // for further upsampling our heavily-oversampled prototype filter. // static void cubicInterpolation(const float* input, float* output, int inputSize, int outputSize, float gain) { - int64_t offset = 0; - int64_t step = ((int64_t)inputSize << 32) / outputSize; // Q32 + + int64_t step = ((int64_t)inputSize << 32) / outputSize; // Q32 + int64_t offset = (outputSize < inputSize) ? (step/2) : 0; // offset to improve small integer ratios // Lagrange interpolation using Farrow structure for (int j = 0; j < outputSize; j++) { @@ -120,19 +134,68 @@ static void cubicInterpolation(const float* input, float* output, int inputSize, } } -int AudioSRC::createPolyphaseFilter(int upFactor, int downFactor, float gain) { +int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { int numPhases = upFactor; - int numCoefs = PROTOTYPE_COEFS; int numTaps = PROTOTYPE_TAPS; - + int numCoefs = PROTOTYPE_TAPS * numPhases; + int oldCoefs = numCoefs; + // // When downsampling, we can lower the filter cutoff by downFactor/upFactor using the // time-scaling property of the Fourier transform. The gain is adjusted accordingly. // if (downFactor > upFactor) { - numCoefs = ((int64_t)PROTOTYPE_COEFS * downFactor) / upFactor; + numCoefs = ((int64_t)oldCoefs * downFactor) / upFactor; numTaps = (numCoefs + upFactor - 1) / upFactor; - gain *= (float)PROTOTYPE_COEFS / numCoefs; + gain *= (float)oldCoefs / numCoefs; + } + + // interpolate the coefficients of the prototype filter + float* tempFilter = new float[numTaps * numPhases]; + memset(tempFilter, 0, numTaps * numPhases * sizeof(float)); + + cubicInterpolation(prototypeFilter, tempFilter, PROTOTYPE_COEFS, numCoefs, gain); + + // create the polyphase filter + _polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 32); + + // rearrange into polyphase form, ordered by use + for (int i = 0; i < numPhases; i++) { + int phase = (i * downFactor) % upFactor; + for (int j = 0; j < numTaps; j++) { + + // the filter taps are reversed, so convolution is implemented as dot-product + float f = tempFilter[(numTaps - j - 1) * numPhases + phase]; + _polyphaseFilter[numTaps * i + j] = f; + } + } + + delete[] tempFilter; + + // precompute the input steps + _stepTable = new int[numPhases]; + + for (int i = 0; i < numPhases; i++) { + _stepTable[i] = (((int64_t)(i+1) * downFactor) / upFactor) - (((int64_t)(i+0) * downFactor) / upFactor); + } + + return numTaps; +} + +int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { + int numPhases = upFactor; + int numTaps = PROTOTYPE_TAPS; + int numCoefs = PROTOTYPE_COEFS; + int oldCoefs = numCoefs; + + // + // When downsampling, we can lower the filter cutoff by downFactor/upFactor using the + // time-scaling property of the Fourier transform. The gain is adjusted accordingly. + // + if (downFactor > upFactor) { + numCoefs = ((int64_t)oldCoefs * downFactor) / upFactor; + numTaps = (numCoefs + upFactor - 1) / upFactor; + gain *= (float)oldCoefs / numCoefs; } // interpolate the coefficients of the prototype filter @@ -154,7 +217,7 @@ int AudioSRC::createPolyphaseFilter(int upFactor, int downFactor, float gain) { } } - delete [] tempFilter; + delete[] tempFilter; // by construction, the last tap of the first phase must be zero assert(_polyphaseFilter[numTaps - 1] == 0.0f); @@ -165,73 +228,140 @@ int AudioSRC::createPolyphaseFilter(int upFactor, int downFactor, float gain) { _polyphaseFilter[numTaps * numPhases + j] = _polyphaseFilter[j-1]; } + _stepTable = nullptr; + return numTaps; } int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) { int outputFrames = 0; - for (; hi32(_offset) < inputFrames; _offset += _step) { + if (_step == 0) { // rational int32_t i = hi32(_offset); - uint32_t f = lo32(_offset); - uint32_t phase = f >> SRC_FRACBITS; - float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT; + while (i < inputFrames) { - const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; - const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; - float acc0 = 0.0f; + float acc0 = 0.0f; - for (int j = 0; j < _numTaps; j++) { + for (int j = 0; j < _numTaps; j++) { - float coef = c0[j] + frac * (c1[j] - c0[j]); + float coef = c0[j]; - acc0 += input0[i + j] * coef; + acc0 += input0[i + j] * c0[j]; + } + + output0[outputFrames] = acc0; + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } } + _offset = (int64_t)(i - inputFrames) << 32; - output0[outputFrames] = acc0; - outputFrames += 1; + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT; + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + float acc0 = 0.0f; + + for (int j = 0; j < _numTaps; j++) { + + float coef = c0[j] + frac * (c1[j] - c0[j]); + + acc0 += input0[i + j] * coef; + } + + output0[outputFrames] = acc0; + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; } - _offset -= (int64_t)inputFrames << 32; - return outputFrames; } int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) { int outputFrames = 0; - for (; hi32(_offset) < inputFrames; _offset += _step) { + if (_step == 0) { // rational int32_t i = hi32(_offset); - uint32_t f = lo32(_offset); - uint32_t phase = f >> SRC_FRACBITS; - float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT; + while (i < inputFrames) { - const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; - const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; - float acc0 = 0.0f; - float acc1 = 0.0f; + float acc0 = 0.0f; + float acc1 = 0.0f; - for (int j = 0; j < _numTaps; j++) { + for (int j = 0; j < _numTaps; j++) { - float coef = c0[j] + frac * (c1[j] - c0[j]); + float coef = c0[j]; - acc0 += input0[i + j] * coef; - acc1 += input1[i + j] * coef; + acc0 += input0[i + j] * c0[j]; + acc1 += input1[i + j] * c0[j]; + } + + output0[outputFrames] = acc0; + output1[outputFrames] = acc1; + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } } + _offset = (int64_t)(i - inputFrames) << 32; - output0[outputFrames] = acc0; - output1[outputFrames] = acc1; - outputFrames += 1; + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + float frac = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT; + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + float acc0 = 0.0f; + float acc1 = 0.0f; + + for (int j = 0; j < _numTaps; j++) { + + float coef = c0[j] + frac * (c1[j] - c0[j]); + + acc0 += input0[i + j] * coef; + acc1 += input1[i + j] * coef; + } + + output0[outputFrames] = acc0; + output1[outputFrames] = acc1; + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; } - _offset -= (int64_t)inputFrames << 32; - return outputFrames; } @@ -255,7 +385,7 @@ void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFram float f = inputs[j][i] * 32768.0f; -#if SRC_DITHER +#ifdef SRC_DITHER // TPDF dither in [-1.0f, 1.0f] static uint32_t rz = 1; int r0 = RAND16(rz); @@ -337,13 +467,25 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) { _outputSampleRate = outputSampleRate; _numChannels = numChannels; - // compute the polyphase filter parameters - _upFactor = SRC_PHASES; - _downFactor = ((int64_t)SRC_PHASES * _inputSampleRate) / _outputSampleRate; - _step = ((int64_t)_inputSampleRate << 32) / _outputSampleRate; + // reduce to the smallest rational fraction + int divisor = gcd(inputSampleRate, outputSampleRate); + _upFactor = outputSampleRate / divisor; + _downFactor = inputSampleRate / divisor; + _step = 0; // rational mode + + // if the number of phases is too large, use irrational mode + if (_upFactor > 640) { + _upFactor = SRC_PHASES; + _downFactor = ((int64_t)SRC_PHASES * _inputSampleRate) / _outputSampleRate; + _step = ((int64_t)_inputSampleRate << 32) / _outputSampleRate; + } // create the polyphase filter - _numTaps = createPolyphaseFilter(_upFactor, _downFactor, 1.0f); + if (_step == 0) { + _numTaps = createRationalFilter(_upFactor, _downFactor, 1.0f); + } else { + _numTaps = createIrrationalFilter(_upFactor, _downFactor, 1.0f); + } //printf("up=%d down=%.3f taps=%d\n", _upFactor, _downFactor + (lo32(_step)<> 32); + if (_step == 0) { + return (int)(((int64_t)outputFrames * _downFactor + _upFactor-1) / _upFactor); + } else { + return (int)(((int64_t)outputFrames * _step + 0xffffffffu) >> 32); + } } // the max input frames that will produce at most outputFrames int AudioSRC::getMaxInput(int outputFrames) { - return (int)((outputFrames * _step) >> 32); + if (_step == 0) { + return (int)(((int64_t)outputFrames * _downFactor) / _upFactor); + } else { + return (int)(((int64_t)outputFrames * _step) >> 32); + } } // diff --git a/libraries/audio/src/AudioSRC.h b/libraries/audio/src/AudioSRC.h index 02aecd3df1..5b00ca9e77 100644 --- a/libraries/audio/src/AudioSRC.h +++ b/libraries/audio/src/AudioSRC.h @@ -31,6 +31,8 @@ public: private: float* _polyphaseFilter; + int* _stepTable; + float* _history[MAX_CHANNELS]; float* _inputs[MAX_CHANNELS]; float* _outputs[MAX_CHANNELS]; @@ -45,10 +47,13 @@ private: int _numTaps; int _numHistory; + int _phase; int64_t _offset; int64_t _step; - int createPolyphaseFilter(int upFactor, int downFactor, float gain); + int createRationalFilter(int upFactor, int downFactor, float gain); + int createIrrationalFilter(int upFactor, int downFactor, float gain); + int multirateFilter1(const float* input0, float* output0, int inputFrames); int multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames); From 956d83c87277b1c94bbc1b297fbe6f13750c6785 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 25 Sep 2015 21:28:48 -0700 Subject: [PATCH 165/418] Size optimization of new resampler. Reduced size of precomputed tables by 8x. Even with 32x oversampling of the prototype filter, aliasing from Lagrange interpolation is (12+24/octave) = -132dB which is fine. --- libraries/audio/src/AudioSRC.cpp | 4620 ++++-------------------------- 1 file changed, 518 insertions(+), 4102 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index e909e870e7..1d3f26e71d 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -19,7 +19,7 @@ // prototype lowpass filter // static const int PROTOTYPE_TAPS = 96; // filter taps per phase -static const int PROTOTYPE_PHASES = 256; // oversampling factor +static const int PROTOTYPE_PHASES = 32; // oversampling factor static const int PROTOTYPE_COEFS = PROTOTYPE_TAPS * PROTOTYPE_PHASES; extern const float prototypeFilter[PROTOTYPE_COEFS]; @@ -135,9 +135,9 @@ static void cubicInterpolation(const float* input, float* output, int inputSize, } int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { - int numPhases = upFactor; int numTaps = PROTOTYPE_TAPS; - int numCoefs = PROTOTYPE_TAPS * numPhases; + int numPhases = upFactor; + int numCoefs = numTaps * numPhases; int oldCoefs = numCoefs; // @@ -183,9 +183,9 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { } int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { - int numPhases = upFactor; int numTaps = PROTOTYPE_TAPS; - int numCoefs = PROTOTYPE_COEFS; + int numPhases = upFactor; + int numCoefs = numTaps * numPhases; int oldCoefs = numCoefs; // @@ -590,7 +590,7 @@ int AudioSRC::getMaxInput(int outputFrames) { // prototype lowpass filter // // Minimum-phase equiripple FIR -// taps = 96, oversampling = 256 +// taps = 96, oversampling = 32 // // passband = 0.918 // stopband = 1.010 @@ -598,4100 +598,516 @@ int AudioSRC::getMaxInput(int outputFrames) { // stopband attn = -125dB (-70dB at 1.000) // const float prototypeFilter[PROTOTYPE_COEFS] = { - 0.00000000e+00f, 8.94334221e-05f, 4.15886168e-06f, 1.15314035e-05f, 1.57443387e-05f, 1.24616776e-05f, - 1.28620094e-05f, 1.39511538e-05f, 1.45614380e-05f, 1.49675544e-05f, 1.58550483e-05f, 1.71848978e-05f, - 1.78226308e-05f, 1.83369205e-05f, 1.87336260e-05f, 1.89712176e-05f, 1.98944111e-05f, 2.20175866e-05f, - 2.27805250e-05f, 2.41839658e-05f, 2.54287793e-05f, 2.59651845e-05f, 2.69671180e-05f, 2.78362086e-05f, - 2.90645956e-05f, 3.05876474e-05f, 3.14942112e-05f, 3.30419567e-05f, 3.47121279e-05f, 3.64973295e-05f, - 3.78851315e-05f, 3.91387705e-05f, 4.05288398e-05f, 4.22712608e-05f, 4.38734574e-05f, 4.52705877e-05f, - 4.65860877e-05f, 4.86168501e-05f, 5.09986905e-05f, 5.29292613e-05f, 5.46954357e-05f, 5.65763591e-05f, - 5.82305985e-05f, 6.01660397e-05f, 6.23488614e-05f, 6.52392981e-05f, 6.75472572e-05f, 6.96044503e-05f, - 7.13912446e-05f, 7.41368720e-05f, 7.69923597e-05f, 7.95897447e-05f, 8.19831310e-05f, 8.45726400e-05f, - 8.74680195e-05f, 9.06947054e-05f, 9.33956167e-05f, 9.60708470e-05f, 9.92105409e-05f, 1.02328768e-04f, - 1.05461829e-04f, 1.08727332e-04f, 1.12140949e-04f, 1.15908052e-04f, 1.19377120e-04f, 1.23060913e-04f, - 1.26689027e-04f, 1.30269471e-04f, 1.33842982e-04f, 1.37972995e-04f, 1.42168591e-04f, 1.46492942e-04f, - 1.51097645e-04f, 1.55197368e-04f, 1.59859724e-04f, 1.64753562e-04f, 1.69534123e-04f, 1.73889035e-04f, - 1.78486031e-04f, 1.83695650e-04f, 1.89118767e-04f, 1.94311160e-04f, 1.99368609e-04f, 2.04789523e-04f, - 2.10690801e-04f, 2.16418369e-04f, 2.22425766e-04f, 2.28424314e-04f, 2.34670821e-04f, 2.41065552e-04f, - 2.47341382e-04f, 2.53792661e-04f, 2.60286107e-04f, 2.67037609e-04f, 2.74122048e-04f, 2.81078446e-04f, - 2.88373471e-04f, 2.95905790e-04f, 3.03617280e-04f, 3.11286840e-04f, 3.19146381e-04f, 3.27263635e-04f, - 3.35550570e-04f, 3.43849874e-04f, 3.52289802e-04f, 3.61060767e-04f, 3.70060670e-04f, 3.79256593e-04f, - 3.88610334e-04f, 3.98085009e-04f, 4.07740918e-04f, 4.17566659e-04f, 4.27579852e-04f, 4.37901408e-04f, - 4.48412528e-04f, 4.58938743e-04f, 4.69649817e-04f, 4.80639200e-04f, 4.91919736e-04f, 5.03272763e-04f, - 5.14932226e-04f, 5.26943009e-04f, 5.39280889e-04f, 5.51826554e-04f, 5.64563447e-04f, 5.77550375e-04f, - 5.90683815e-04f, 6.04012743e-04f, 6.17515236e-04f, 6.31170586e-04f, 6.45018907e-04f, 6.59414261e-04f, - 6.74456798e-04f, 6.89469608e-04f, 7.04530039e-04f, 7.19947432e-04f, 7.35613742e-04f, 7.51766459e-04f, - 7.68010966e-04f, 7.84621405e-04f, 8.01341935e-04f, 8.18555396e-04f, 8.36099068e-04f, 8.54135354e-04f, - 8.72321365e-04f, 8.90731676e-04f, 9.09447817e-04f, 9.28494437e-04f, 9.47958594e-04f, 9.67657717e-04f, - 9.87926859e-04f, 1.00842047e-03f, 1.02926019e-03f, 1.05036747e-03f, 1.07197243e-03f, 1.09372294e-03f, - 1.11606358e-03f, 1.13866880e-03f, 1.16172322e-03f, 1.18511783e-03f, 1.20893021e-03f, 1.23309248e-03f, - 1.25780021e-03f, 1.28285763e-03f, 1.30826165e-03f, 1.33399248e-03f, 1.36033799e-03f, 1.38706675e-03f, - 1.41424061e-03f, 1.44186516e-03f, 1.46981808e-03f, 1.49823826e-03f, 1.52719311e-03f, 1.55665258e-03f, - 1.58642001e-03f, 1.61686942e-03f, 1.64769311e-03f, 1.67892921e-03f, 1.71075334e-03f, 1.74311128e-03f, - 1.77591925e-03f, 1.80908277e-03f, 1.84312222e-03f, 1.87744004e-03f, 1.91237159e-03f, 1.94786548e-03f, - 1.98384635e-03f, 2.02030432e-03f, 2.05744894e-03f, 2.09514182e-03f, 2.13328355e-03f, 2.17211450e-03f, - 2.21150815e-03f, 2.25160810e-03f, 2.29209960e-03f, 2.33329997e-03f, 2.37500201e-03f, 2.41755276e-03f, - 2.46069326e-03f, 2.50454125e-03f, 2.54880529e-03f, 2.59383369e-03f, 2.63945219e-03f, 2.68576670e-03f, - 2.73282434e-03f, 2.78058495e-03f, 2.82909833e-03f, 2.87796809e-03f, 2.92780994e-03f, 2.97820723e-03f, - 3.02954913e-03f, 3.08158298e-03f, 3.13457267e-03f, 3.18804207e-03f, 3.24224741e-03f, 3.29710420e-03f, - 3.35278749e-03f, 3.40918556e-03f, 3.46671991e-03f, 3.52485958e-03f, 3.58369614e-03f, 3.64354146e-03f, - 3.70418183e-03f, 3.76557438e-03f, 3.82767481e-03f, 3.89072601e-03f, 3.95481499e-03f, 4.01980810e-03f, - 4.08560856e-03f, 4.15223096e-03f, 4.21974817e-03f, 4.28828202e-03f, 4.35759406e-03f, 4.42774927e-03f, - 4.49900248e-03f, 4.57119642e-03f, 4.64436796e-03f, 4.71864483e-03f, 4.79379091e-03f, 4.86965321e-03f, - 4.94659225e-03f, 5.02470108e-03f, 5.10387604e-03f, 5.18416600e-03f, 5.26550451e-03f, 5.34775630e-03f, - 5.43092616e-03f, 5.51523201e-03f, 5.60064590e-03f, 5.68719319e-03f, 5.77488775e-03f, 5.86368613e-03f, - 5.95373420e-03f, 6.04478188e-03f, 6.13690559e-03f, 6.23029790e-03f, 6.32497154e-03f, 6.42076062e-03f, - 6.51735353e-03f, 6.61551641e-03f, 6.71481750e-03f, 6.81539493e-03f, 6.91714954e-03f, 7.02031885e-03f, - 7.12470729e-03f, 7.23017078e-03f, 7.33711613e-03f, 7.44535645e-03f, 7.55488235e-03f, 7.66571290e-03f, - 7.77792057e-03f, 7.89152427e-03f, 8.00643155e-03f, 8.12258918e-03f, 8.24023444e-03f, 8.35929722e-03f, - 8.47973184e-03f, 8.60160669e-03f, 8.72508058e-03f, 8.84999034e-03f, 8.97621471e-03f, 9.10394295e-03f, - 9.23318675e-03f, 9.36385019e-03f, 9.49606943e-03f, 9.62996679e-03f, 9.76530755e-03f, 9.90227712e-03f, - 1.00406898e-02f, 1.01806878e-02f, 1.03223763e-02f, 1.04656291e-02f, 1.06106232e-02f, 1.07571701e-02f, - 1.09054344e-02f, 1.10552334e-02f, 1.12066991e-02f, 1.13600345e-02f, 1.15151259e-02f, 1.16717960e-02f, - 1.18303010e-02f, 1.19904523e-02f, 1.21523865e-02f, 1.23160663e-02f, 1.24817924e-02f, 1.26491067e-02f, - 1.28184170e-02f, 1.29894464e-02f, 1.31623439e-02f, 1.33371284e-02f, 1.35138671e-02f, 1.36925684e-02f, - 1.38731223e-02f, 1.40555478e-02f, 1.42398372e-02f, 1.44262176e-02f, 1.46146416e-02f, 1.48050381e-02f, - 1.49972300e-02f, 1.51917587e-02f, 1.53881928e-02f, 1.55866558e-02f, 1.57872773e-02f, 1.59901153e-02f, - 1.61947504e-02f, 1.64016225e-02f, 1.66107253e-02f, 1.68219185e-02f, 1.70352825e-02f, 1.72509251e-02f, - 1.74687600e-02f, 1.76887181e-02f, 1.79108639e-02f, 1.81353466e-02f, 1.83622737e-02f, 1.85913569e-02f, - 1.88228520e-02f, 1.90564810e-02f, 1.92924625e-02f, 1.95308378e-02f, 1.97715963e-02f, 2.00147284e-02f, - 2.02603888e-02f, 2.05083932e-02f, 2.07586990e-02f, 2.10115314e-02f, 2.12670241e-02f, 2.15247815e-02f, - 2.17851805e-02f, 2.20481579e-02f, 2.23136920e-02f, 2.25817543e-02f, 2.28524142e-02f, 2.31255329e-02f, - 2.34010010e-02f, 2.36793503e-02f, 2.39605526e-02f, 2.42444272e-02f, 2.45310260e-02f, 2.48202488e-02f, - 2.51120271e-02f, 2.54064913e-02f, 2.57036901e-02f, 2.60036315e-02f, 2.63067493e-02f, 2.66127946e-02f, - 2.69214527e-02f, 2.72327272e-02f, 2.75469377e-02f, 2.78638714e-02f, 2.81837618e-02f, 2.85068870e-02f, - 2.88330354e-02f, 2.91618476e-02f, 2.94936350e-02f, 2.98285440e-02f, 3.01665331e-02f, 3.05074338e-02f, - 3.08513233e-02f, 3.11981951e-02f, 3.15481736e-02f, 3.19014093e-02f, 3.22577795e-02f, 3.26173459e-02f, - 3.29798702e-02f, 3.33456677e-02f, 3.37145744e-02f, 3.40867626e-02f, 3.44621832e-02f, 3.48408942e-02f, - 3.52228883e-02f, 3.56080803e-02f, 3.59965410e-02f, 3.63884234e-02f, 3.67835873e-02f, 3.71822142e-02f, - 3.75841582e-02f, 3.79894736e-02f, 3.83982958e-02f, 3.88104589e-02f, 3.92260854e-02f, 3.96451460e-02f, - 4.00678000e-02f, 4.04940162e-02f, 4.09236745e-02f, 4.13568664e-02f, 4.17936026e-02f, 4.22340028e-02f, - 4.26780239e-02f, 4.31255426e-02f, 4.35767862e-02f, 4.40316923e-02f, 4.44902566e-02f, 4.49525397e-02f, - 4.54184090e-02f, 4.58881302e-02f, 4.63617141e-02f, 4.68389395e-02f, 4.73199736e-02f, 4.78047723e-02f, - 4.82934051e-02f, 4.87859471e-02f, 4.92822693e-02f, 4.97825595e-02f, 5.02866532e-02f, 5.07947537e-02f, - 5.13067228e-02f, 5.18226704e-02f, 5.23425496e-02f, 5.28665320e-02f, 5.33944769e-02f, 5.39264255e-02f, - 5.44623360e-02f, 5.50023605e-02f, 5.55465011e-02f, 5.60947931e-02f, 5.66471339e-02f, 5.72035924e-02f, - 5.77642010e-02f, 5.83289605e-02f, 5.88979703e-02f, 5.94711291e-02f, 6.00486012e-02f, 6.06302001e-02f, - 6.12160838e-02f, 6.18062217e-02f, 6.24007239e-02f, 6.29994618e-02f, 6.36025283e-02f, 6.42099754e-02f, - 6.48217655e-02f, 6.54378884e-02f, 6.60584380e-02f, 6.66833206e-02f, 6.73127038e-02f, 6.79465577e-02f, - 6.85848605e-02f, 6.92276808e-02f, 6.98748650e-02f, 7.05266413e-02f, 7.11829172e-02f, 7.18437849e-02f, - 7.25091110e-02f, 7.31790310e-02f, 7.38535400e-02f, 7.45326360e-02f, 7.52163396e-02f, 7.59047102e-02f, - 7.65977522e-02f, 7.72954478e-02f, 7.79978742e-02f, 7.87048818e-02f, 7.94167040e-02f, 8.01332281e-02f, - 8.08544747e-02f, 8.15803825e-02f, 8.23111249e-02f, 8.30466371e-02f, 8.37869515e-02f, 8.45320796e-02f, - 8.52820276e-02f, 8.60368812e-02f, 8.67965379e-02f, 8.75610590e-02f, 8.83304682e-02f, 8.91047783e-02f, - 8.98839137e-02f, 9.06680436e-02f, 9.14571240e-02f, 9.22510910e-02f, 9.30499998e-02f, 9.38538573e-02f, - 9.46627269e-02f, 9.54766488e-02f, 9.62955879e-02f, 9.71194636e-02f, 9.79484431e-02f, 9.87823674e-02f, - 9.96214263e-02f, 1.00465519e-01f, 1.01314736e-01f, 1.02168995e-01f, 1.03028289e-01f, 1.03892722e-01f, - 1.04762326e-01f, 1.05637099e-01f, 1.06516955e-01f, 1.07402010e-01f, 1.08292135e-01f, 1.09187486e-01f, - 1.10087941e-01f, 1.10993600e-01f, 1.11904446e-01f, 1.12820546e-01f, 1.13741881e-01f, 1.14668478e-01f, - 1.15600317e-01f, 1.16537295e-01f, 1.17479530e-01f, 1.18426966e-01f, 1.19379788e-01f, 1.20337794e-01f, - 1.21301099e-01f, 1.22269652e-01f, 1.23243525e-01f, 1.24222799e-01f, 1.25207269e-01f, 1.26197100e-01f, - 1.27192252e-01f, 1.28192692e-01f, 1.29198402e-01f, 1.30209494e-01f, 1.31225882e-01f, 1.32247631e-01f, - 1.33274764e-01f, 1.34307254e-01f, 1.35345103e-01f, 1.36388282e-01f, 1.37436761e-01f, 1.38490699e-01f, - 1.39549995e-01f, 1.40614640e-01f, 1.41684677e-01f, 1.42760026e-01f, 1.43840813e-01f, 1.44926977e-01f, - 1.46018481e-01f, 1.47115340e-01f, 1.48217670e-01f, 1.49325339e-01f, 1.50438398e-01f, 1.51556921e-01f, - 1.52680717e-01f, 1.53809941e-01f, 1.54944432e-01f, 1.56084449e-01f, 1.57229898e-01f, 1.58380757e-01f, - 1.59536871e-01f, 1.60698341e-01f, 1.61865202e-01f, 1.63037495e-01f, 1.64215165e-01f, 1.65398097e-01f, - 1.66586537e-01f, 1.67780262e-01f, 1.68979344e-01f, 1.70183792e-01f, 1.71393565e-01f, 1.72608690e-01f, - 1.73829273e-01f, 1.75055161e-01f, 1.76286281e-01f, 1.77522739e-01f, 1.78764462e-01f, 1.80011609e-01f, - 1.81264020e-01f, 1.82521697e-01f, 1.83784706e-01f, 1.85052992e-01f, 1.86326537e-01f, 1.87605285e-01f, - 1.88889430e-01f, 1.90178719e-01f, 1.91473371e-01f, 1.92773095e-01f, 1.94078089e-01f, 1.95388337e-01f, - 1.96703747e-01f, 1.98024288e-01f, 1.99350106e-01f, 2.00681004e-01f, 2.02017128e-01f, 2.03358363e-01f, - 2.04704724e-01f, 2.06056246e-01f, 2.07412833e-01f, 2.08774422e-01f, 2.10141130e-01f, 2.11512933e-01f, - 2.12889776e-01f, 2.14271687e-01f, 2.15658535e-01f, 2.17050423e-01f, 2.18447302e-01f, 2.19849110e-01f, - 2.21255879e-01f, 2.22667512e-01f, 2.24084181e-01f, 2.25505746e-01f, 2.26932101e-01f, 2.28363315e-01f, - 2.29799478e-01f, 2.31240404e-01f, 2.32686084e-01f, 2.34136527e-01f, 2.35591794e-01f, 2.37051771e-01f, - 2.38516556e-01f, 2.39985883e-01f, 2.41459997e-01f, 2.42938691e-01f, 2.44422074e-01f, 2.45910028e-01f, - 2.47402628e-01f, 2.48899789e-01f, 2.50401440e-01f, 2.51907629e-01f, 2.53418299e-01f, 2.54933496e-01f, - 2.56452946e-01f, 2.57976863e-01f, 2.59505102e-01f, 2.61037763e-01f, 2.62574766e-01f, 2.64116139e-01f, - 2.65661804e-01f, 2.67211727e-01f, 2.68765800e-01f, 2.70324071e-01f, 2.71886394e-01f, 2.73452835e-01f, - 2.75023452e-01f, 2.76598183e-01f, 2.78176908e-01f, 2.79759568e-01f, 2.81346172e-01f, 2.82936821e-01f, - 2.84531364e-01f, 2.86129776e-01f, 2.87732054e-01f, 2.89338097e-01f, 2.90947878e-01f, 2.92561386e-01f, - 2.94178624e-01f, 2.95799572e-01f, 2.97424149e-01f, 2.99052242e-01f, 3.00683859e-01f, 3.02319017e-01f, - 3.03957712e-01f, 3.05599857e-01f, 3.07245362e-01f, 3.08894225e-01f, 3.10546419e-01f, 3.12201948e-01f, - 3.13860688e-01f, 3.15522582e-01f, 3.17187617e-01f, 3.18855907e-01f, 3.20527183e-01f, 3.22201531e-01f, - 3.23878790e-01f, 3.25559048e-01f, 3.27242267e-01f, 3.28928344e-01f, 3.30617199e-01f, 3.32308817e-01f, - 3.34003212e-01f, 3.35700318e-01f, 3.37400126e-01f, 3.39102233e-01f, 3.40807130e-01f, 3.42514390e-01f, - 3.44224264e-01f, 3.45936454e-01f, 3.47650971e-01f, 3.49367805e-01f, 3.51086909e-01f, 3.52808273e-01f, - 3.54531741e-01f, 3.56257333e-01f, 3.57985003e-01f, 3.59714713e-01f, 3.61446334e-01f, 3.63179778e-01f, - 3.64915133e-01f, 3.66652296e-01f, 3.68391232e-01f, 3.70131793e-01f, 3.71873991e-01f, 3.73617811e-01f, - 3.75363181e-01f, 3.77110003e-01f, 3.78858218e-01f, 3.80607775e-01f, 3.82358707e-01f, 3.84110833e-01f, - 3.85864178e-01f, 3.87618704e-01f, 3.89374245e-01f, 3.91130883e-01f, 3.92888323e-01f, 3.94646726e-01f, - 3.96405985e-01f, 3.98166096e-01f, 3.99926898e-01f, 4.01688362e-01f, 4.03450280e-01f, 4.05212872e-01f, - 4.06975903e-01f, 4.08739460e-01f, 4.10503234e-01f, 4.12267362e-01f, 4.14031711e-01f, 4.15796220e-01f, - 4.17560791e-01f, 4.19325419e-01f, 4.21089972e-01f, 4.22854439e-01f, 4.24618869e-01f, 4.26383005e-01f, - 4.28146877e-01f, 4.29910258e-01f, 4.31673272e-01f, 4.33435834e-01f, 4.35197911e-01f, 4.36959275e-01f, - 4.38719908e-01f, 4.40479772e-01f, 4.42238847e-01f, 4.43997137e-01f, 4.45754333e-01f, 4.47510469e-01f, - 4.49265473e-01f, 4.51019314e-01f, 4.52771955e-01f, 4.54523275e-01f, 4.56273090e-01f, 4.58021590e-01f, - 4.59768507e-01f, 4.61513817e-01f, 4.63257408e-01f, 4.64999142e-01f, 4.66739162e-01f, 4.68477322e-01f, - 4.70213476e-01f, 4.71947531e-01f, 4.73679510e-01f, 4.75409262e-01f, 4.77136720e-01f, 4.78861796e-01f, - 4.80584440e-01f, 4.82304651e-01f, 4.84022312e-01f, 4.85737286e-01f, 4.87449476e-01f, 4.89158865e-01f, - 4.90865346e-01f, 4.92568950e-01f, 4.94269501e-01f, 4.95966906e-01f, 4.97661061e-01f, 4.99352034e-01f, - 5.01039565e-01f, 5.02723719e-01f, 5.04404332e-01f, 5.06081350e-01f, 5.07754764e-01f, 5.09424313e-01f, - 5.11090048e-01f, 5.12751809e-01f, 5.14409713e-01f, 5.16063505e-01f, 5.17713203e-01f, 5.19358459e-01f, - 5.20999524e-01f, 5.22636149e-01f, 5.24268371e-01f, 5.25895969e-01f, 5.27518900e-01f, 5.29137199e-01f, - 5.30750631e-01f, 5.32359137e-01f, 5.33962590e-01f, 5.35561123e-01f, 5.37154448e-01f, 5.38742601e-01f, - 5.40325333e-01f, 5.41902713e-01f, 5.43474578e-01f, 5.45041008e-01f, 5.46601675e-01f, 5.48156667e-01f, - 5.49705710e-01f, 5.51248905e-01f, 5.52786258e-01f, 5.54317488e-01f, 5.55842550e-01f, 5.57361242e-01f, - 5.58873737e-01f, 5.60379755e-01f, 5.61879247e-01f, 5.63372156e-01f, 5.64858477e-01f, 5.66338068e-01f, - 5.67810779e-01f, 5.69276490e-01f, 5.70735202e-01f, 5.72186843e-01f, 5.73631356e-01f, 5.75068585e-01f, - 5.76498409e-01f, 5.77920887e-01f, 5.79335617e-01f, 5.80742917e-01f, 5.82142401e-01f, 5.83534237e-01f, - 5.84918079e-01f, 5.86294021e-01f, 5.87661882e-01f, 5.89021639e-01f, 5.90373190e-01f, 5.91716352e-01f, - 5.93051227e-01f, 5.94377501e-01f, 5.95695274e-01f, 5.97004436e-01f, 5.98304800e-01f, 5.99596383e-01f, - 6.00879012e-01f, 6.02152708e-01f, 6.03417276e-01f, 6.04672676e-01f, 6.05918865e-01f, 6.07155655e-01f, - 6.08382988e-01f, 6.09600894e-01f, 6.10809136e-01f, 6.12007691e-01f, 6.13196549e-01f, 6.14375489e-01f, - 6.15544573e-01f, 6.16703525e-01f, 6.17852353e-01f, 6.18991064e-01f, 6.20119569e-01f, 6.21237637e-01f, - 6.22345163e-01f, 6.23442249e-01f, 6.24528723e-01f, 6.25604501e-01f, 6.26669346e-01f, 6.27723406e-01f, - 6.28766589e-01f, 6.29798698e-01f, 6.30819656e-01f, 6.31829420e-01f, 6.32827933e-01f, 6.33815080e-01f, - 6.34790681e-01f, 6.35754772e-01f, 6.36707347e-01f, 6.37648183e-01f, 6.38577249e-01f, 6.39494408e-01f, - 6.40399567e-01f, 6.41292726e-01f, 6.42173909e-01f, 6.43042876e-01f, 6.43899564e-01f, 6.44743860e-01f, - 6.45575703e-01f, 6.46395099e-01f, 6.47201891e-01f, 6.47996096e-01f, 6.48777498e-01f, 6.49546145e-01f, - 6.50301831e-01f, 6.51044571e-01f, 6.51774203e-01f, 6.52490788e-01f, 6.53194104e-01f, 6.53884288e-01f, - 6.54561048e-01f, 6.55224291e-01f, 6.55874069e-01f, 6.56510300e-01f, 6.57132862e-01f, 6.57741716e-01f, - 6.58336759e-01f, 6.58917986e-01f, 6.59485226e-01f, 6.60038375e-01f, 6.60577513e-01f, 6.61102386e-01f, - 6.61613223e-01f, 6.62109652e-01f, 6.62591761e-01f, 6.63059310e-01f, 6.63512363e-01f, 6.63950923e-01f, - 6.64374743e-01f, 6.64783890e-01f, 6.65178225e-01f, 6.65557771e-01f, 6.65922408e-01f, 6.66272020e-01f, - 6.66606529e-01f, 6.66925974e-01f, 6.67230187e-01f, 6.67519276e-01f, 6.67792998e-01f, 6.68051298e-01f, - 6.68294187e-01f, 6.68521681e-01f, 6.68733496e-01f, 6.68929699e-01f, 6.69110230e-01f, 6.69275047e-01f, - 6.69424131e-01f, 6.69557310e-01f, 6.69674617e-01f, 6.69775916e-01f, 6.69861192e-01f, 6.69930315e-01f, - 6.69983267e-01f, 6.70020168e-01f, 6.70040768e-01f, 6.70045107e-01f, 6.70033101e-01f, 6.70004544e-01f, - 6.69959613e-01f, 6.69898159e-01f, 6.69820179e-01f, 6.69725525e-01f, 6.69614231e-01f, 6.69486301e-01f, - 6.69341628e-01f, 6.69180069e-01f, 6.69001579e-01f, 6.68806170e-01f, 6.68594059e-01f, 6.68364776e-01f, - 6.68118510e-01f, 6.67855175e-01f, 6.67574723e-01f, 6.67277178e-01f, 6.66962303e-01f, 6.66630184e-01f, - 6.66280782e-01f, 6.65914167e-01f, 6.65530293e-01f, 6.65128804e-01f, 6.64709897e-01f, 6.64273594e-01f, - 6.63819805e-01f, 6.63348468e-01f, 6.62859484e-01f, 6.62352885e-01f, 6.61828768e-01f, 6.61286955e-01f, - 6.60727440e-01f, 6.60150121e-01f, 6.59555193e-01f, 6.58942377e-01f, 6.58311737e-01f, 6.57663269e-01f, - 6.56996960e-01f, 6.56312777e-01f, 6.55610673e-01f, 6.54890599e-01f, 6.54152640e-01f, 6.53396601e-01f, - 6.52622635e-01f, 6.51830648e-01f, 6.51020601e-01f, 6.50192545e-01f, 6.49346311e-01f, 6.48482072e-01f, - 6.47599764e-01f, 6.46699245e-01f, 6.45780610e-01f, 6.44843761e-01f, 6.43888876e-01f, 6.42915871e-01f, - 6.41924583e-01f, 6.40915105e-01f, 6.39887431e-01f, 6.38841588e-01f, 6.37777551e-01f, 6.36695242e-01f, - 6.35594706e-01f, 6.34475994e-01f, 6.33339121e-01f, 6.32183889e-01f, 6.31010372e-01f, 6.29818778e-01f, - 6.28608898e-01f, 6.27380900e-01f, 6.26134441e-01f, 6.24869920e-01f, 6.23587179e-01f, 6.22286270e-01f, - 6.20967109e-01f, 6.19629647e-01f, 6.18274030e-01f, 6.16900381e-01f, 6.15508446e-01f, 6.14098430e-01f, - 6.12670269e-01f, 6.11223920e-01f, 6.09759497e-01f, 6.08276888e-01f, 6.06776278e-01f, 6.05257566e-01f, - 6.03720883e-01f, 6.02166177e-01f, 6.00593314e-01f, 5.99002625e-01f, 5.97393939e-01f, 5.95767179e-01f, - 5.94122523e-01f, 5.92460117e-01f, 5.90779882e-01f, 5.89081753e-01f, 5.87365633e-01f, 5.85631900e-01f, - 5.83880388e-01f, 5.82111269e-01f, 5.80324267e-01f, 5.78519661e-01f, 5.76697616e-01f, 5.74857882e-01f, - 5.73000552e-01f, 5.71125613e-01f, 5.69233358e-01f, 5.67323719e-01f, 5.65396717e-01f, 5.63452261e-01f, - 5.61490478e-01f, 5.59511453e-01f, 5.57515337e-01f, 5.55501943e-01f, 5.53471365e-01f, 5.51423750e-01f, - 5.49359235e-01f, 5.47277732e-01f, 5.45179144e-01f, 5.43063845e-01f, 5.40931616e-01f, 5.38782642e-01f, - 5.36617030e-01f, 5.34434699e-01f, 5.32235832e-01f, 5.30020386e-01f, 5.27788487e-01f, 5.25540099e-01f, - 5.23275408e-01f, 5.20994361e-01f, 5.18697203e-01f, 5.16383803e-01f, 5.14054387e-01f, 5.11708806e-01f, - 5.09347320e-01f, 5.06969910e-01f, 5.04576757e-01f, 5.02167775e-01f, 4.99743151e-01f, 4.97302862e-01f, - 4.94847049e-01f, 4.92375777e-01f, 4.89889096e-01f, 4.87387156e-01f, 4.84869930e-01f, 4.82337576e-01f, - 4.79790162e-01f, 4.77227748e-01f, 4.74650378e-01f, 4.72058262e-01f, 4.69451228e-01f, 4.66829697e-01f, - 4.64193566e-01f, 4.61542971e-01f, 4.58877863e-01f, 4.56198495e-01f, 4.53504947e-01f, 4.50797223e-01f, - 4.48075415e-01f, 4.45339770e-01f, 4.42590257e-01f, 4.39826938e-01f, 4.37049955e-01f, 4.34259397e-01f, - 4.31455375e-01f, 4.28638017e-01f, 4.25807374e-01f, 4.22963573e-01f, 4.20106712e-01f, 4.17236910e-01f, - 4.14354140e-01f, 4.11458662e-01f, 4.08550500e-01f, 4.05629924e-01f, 4.02696846e-01f, 3.99751390e-01f, - 3.96793756e-01f, 3.93824009e-01f, 3.90842286e-01f, 3.87848558e-01f, 3.84843178e-01f, 3.81826081e-01f, - 3.78797526e-01f, 3.75757451e-01f, 3.72706079e-01f, 3.69643503e-01f, 3.66569814e-01f, 3.63485136e-01f, - 3.60389758e-01f, 3.57283689e-01f, 3.54166931e-01f, 3.51039568e-01f, 3.47902006e-01f, 3.44754175e-01f, - 3.41596282e-01f, 3.38428367e-01f, 3.35250624e-01f, 3.32063227e-01f, 3.28866158e-01f, 3.25659527e-01f, - 3.22443639e-01f, 3.19218596e-01f, 3.15984481e-01f, 3.12741416e-01f, 3.09489470e-01f, 3.06228966e-01f, - 3.02959767e-01f, 2.99682267e-01f, 2.96396573e-01f, 2.93102629e-01f, 2.89800769e-01f, 2.86491004e-01f, - 2.83173528e-01f, 2.79848505e-01f, 2.76516018e-01f, 2.73176159e-01f, 2.69829222e-01f, 2.66475446e-01f, - 2.63114667e-01f, 2.59747044e-01f, 2.56373024e-01f, 2.52992527e-01f, 2.49605732e-01f, 2.46212735e-01f, - 2.42813764e-01f, 2.39409130e-01f, 2.35998626e-01f, 2.32582555e-01f, 2.29161152e-01f, 2.25734573e-01f, - 2.22302889e-01f, 2.18866076e-01f, 2.15424552e-01f, 2.11978613e-01f, 2.08528090e-01f, 2.05073211e-01f, - 2.01613980e-01f, 1.98150993e-01f, 1.94684032e-01f, 1.91213305e-01f, 1.87739035e-01f, 1.84261490e-01f, - 1.80780780e-01f, 1.77296831e-01f, 1.73809903e-01f, 1.70320372e-01f, 1.66828158e-01f, 1.63333639e-01f, - 1.59836709e-01f, 1.56337604e-01f, 1.52836763e-01f, 1.49333948e-01f, 1.45829524e-01f, 1.42323668e-01f, - 1.38816597e-01f, 1.35308277e-01f, 1.31798890e-01f, 1.28288831e-01f, 1.24778148e-01f, 1.21266867e-01f, - 1.17755415e-01f, 1.14243677e-01f, 1.10732081e-01f, 1.07220554e-01f, 1.03709261e-01f, 1.00198634e-01f, - 9.66886501e-02f, 9.31797373e-02f, 8.96714068e-02f, 8.61646183e-02f, 8.26590898e-02f, 7.91549939e-02f, - 7.56526429e-02f, 7.21521398e-02f, 6.86536031e-02f, 6.51573687e-02f, 6.16635554e-02f, 5.81722439e-02f, - 5.46835627e-02f, 5.11975346e-02f, 4.77148305e-02f, 4.42351943e-02f, 4.07592311e-02f, 3.72864777e-02f, - 3.38176420e-02f, 3.03527324e-02f, 2.68918388e-02f, 2.34350487e-02f, 1.99826847e-02f, 1.65350230e-02f, - 1.30921881e-02f, 9.65408473e-03f, 6.22109888e-03f, 2.79333966e-03f, -6.28805357e-04f, -4.04542201e-03f, - -7.45639835e-03f, -1.08614406e-02f, -1.42602959e-02f, -1.76527609e-02f, -2.10388329e-02f, -2.44183025e-02f, - -2.77910910e-02f, -3.11568005e-02f, -3.45154447e-02f, -3.78666793e-02f, -4.12105335e-02f, -4.45466496e-02f, - -4.78750509e-02f, -5.11954789e-02f, -5.45077195e-02f, -5.78116476e-02f, -6.11070889e-02f, -6.43938758e-02f, - -6.76718427e-02f, -7.09407885e-02f, -7.42006059e-02f, -7.74511094e-02f, -8.06921774e-02f, -8.39234614e-02f, - -8.71448947e-02f, -9.03564980e-02f, -9.35579516e-02f, -9.67489878e-02f, -9.99294722e-02f, -1.03099359e-01f, - -1.06258564e-01f, -1.09406753e-01f, -1.12543599e-01f, -1.15669205e-01f, -1.18783524e-01f, -1.21886193e-01f, - -1.24976946e-01f, -1.28055645e-01f, -1.31122362e-01f, -1.34176926e-01f, -1.37218937e-01f, -1.40248289e-01f, - -1.43264889e-01f, -1.46268685e-01f, -1.49259499e-01f, -1.52236945e-01f, -1.55200927e-01f, -1.58151493e-01f, - -1.61088426e-01f, -1.64011390e-01f, -1.66920361e-01f, -1.69815260e-01f, -1.72695856e-01f, -1.75561911e-01f, - -1.78413393e-01f, -1.81249996e-01f, -1.84071816e-01f, -1.86878580e-01f, -1.89670100e-01f, -1.92446290e-01f, - -1.95206901e-01f, -1.97951932e-01f, -2.00681101e-01f, -2.03394333e-01f, -2.06091494e-01f, -2.08772431e-01f, - -2.11436968e-01f, -2.14084978e-01f, -2.16716383e-01f, -2.19330964e-01f, -2.21928546e-01f, -2.24509031e-01f, - -2.27072344e-01f, -2.29618409e-01f, -2.32146871e-01f, -2.34657702e-01f, -2.37150718e-01f, -2.39625920e-01f, - -2.42083147e-01f, -2.44522183e-01f, -2.46942785e-01f, -2.49345063e-01f, -2.51728883e-01f, -2.54093973e-01f, - -2.56440182e-01f, -2.58767364e-01f, -2.61075678e-01f, -2.63364909e-01f, -2.65634707e-01f, -2.67884981e-01f, - -2.70115683e-01f, -2.72326888e-01f, -2.74518379e-01f, -2.76689787e-01f, -2.78841107e-01f, -2.80972440e-01f, - -2.83083553e-01f, -2.85174263e-01f, -2.87244351e-01f, -2.89293922e-01f, -2.91322989e-01f, -2.93331110e-01f, - -2.95318292e-01f, -2.97284396e-01f, -2.99229490e-01f, -3.01153368e-01f, -3.03055845e-01f, -3.04936847e-01f, - -3.06796414e-01f, -3.08634276e-01f, -3.10450469e-01f, -3.12244777e-01f, -3.14017112e-01f, -3.15767529e-01f, - -3.17495755e-01f, -3.19201819e-01f, -3.20885535e-01f, -3.22546909e-01f, -3.24185825e-01f, -3.25802157e-01f, - -3.27395725e-01f, -3.28966738e-01f, -3.30514879e-01f, -3.32040174e-01f, -3.33542317e-01f, -3.35021503e-01f, - -3.36477640e-01f, -3.37910606e-01f, -3.39320041e-01f, -3.40706148e-01f, -3.42068975e-01f, -3.43408309e-01f, - -3.44724098e-01f, -3.46015982e-01f, -3.47284276e-01f, -3.48529051e-01f, -3.49749848e-01f, -3.50946606e-01f, - -3.52119388e-01f, -3.53268349e-01f, -3.54393271e-01f, -3.55493982e-01f, -3.56570298e-01f, -3.57622536e-01f, - -3.58650580e-01f, -3.59654207e-01f, -3.60633351e-01f, -3.61588096e-01f, -3.62518458e-01f, -3.63424291e-01f, - -3.64305358e-01f, -3.65161934e-01f, -3.65993890e-01f, -3.66801151e-01f, -3.67583633e-01f, -3.68341245e-01f, - -3.69074186e-01f, -3.69782304e-01f, -3.70465570e-01f, -3.71123824e-01f, -3.71757250e-01f, -3.72365692e-01f, - -3.72949178e-01f, -3.73507671e-01f, -3.74041153e-01f, -3.74549541e-01f, -3.75032899e-01f, -3.75491158e-01f, - -3.75924391e-01f, -3.76332564e-01f, -3.76715465e-01f, -3.77073225e-01f, -3.77405972e-01f, -3.77713565e-01f, - -3.77996176e-01f, -3.78253295e-01f, -3.78485359e-01f, -3.78692363e-01f, -3.78874183e-01f, -3.79030878e-01f, - -3.79162336e-01f, -3.79268573e-01f, -3.79349926e-01f, -3.79406085e-01f, -3.79436952e-01f, -3.79442687e-01f, - -3.79423466e-01f, -3.79379315e-01f, -3.79310032e-01f, -3.79215381e-01f, -3.79095810e-01f, -3.78951589e-01f, - -3.78782247e-01f, -3.78587834e-01f, -3.78368268e-01f, -3.78124137e-01f, -3.77855304e-01f, -3.77561389e-01f, - -3.77242456e-01f, -3.76898972e-01f, -3.76530819e-01f, -3.76138049e-01f, -3.75720352e-01f, -3.75278073e-01f, - -3.74811391e-01f, -3.74320197e-01f, -3.73804299e-01f, -3.73264050e-01f, -3.72699466e-01f, -3.72110559e-01f, - -3.71497352e-01f, -3.70859954e-01f, -3.70198306e-01f, -3.69512578e-01f, -3.68802751e-01f, -3.68068973e-01f, - -3.67311276e-01f, -3.66529671e-01f, -3.65724348e-01f, -3.64895123e-01f, -3.64042390e-01f, -3.63166007e-01f, - -3.62266058e-01f, -3.61342710e-01f, -3.60395889e-01f, -3.59425851e-01f, -3.58432590e-01f, -3.57416208e-01f, - -3.56376674e-01f, -3.55314188e-01f, -3.54228775e-01f, -3.53120612e-01f, -3.51989653e-01f, -3.50836109e-01f, - -3.49660101e-01f, -3.48461492e-01f, -3.47240680e-01f, -3.45997439e-01f, -3.44732159e-01f, -3.43444709e-01f, - -3.42135382e-01f, -3.40804096e-01f, -3.39451130e-01f, -3.38076415e-01f, -3.36680179e-01f, -3.35262504e-01f, - -3.33823526e-01f, -3.32363299e-01f, -3.30881944e-01f, -3.29379532e-01f, -3.27856267e-01f, -3.26312279e-01f, - -3.24747603e-01f, -3.23162346e-01f, -3.21556651e-01f, -3.19930690e-01f, -3.18284603e-01f, -3.16618399e-01f, - -3.14932298e-01f, -3.13226395e-01f, -3.11500827e-01f, -3.09755686e-01f, -3.07991208e-01f, -3.06207438e-01f, - -3.04404501e-01f, -3.02582537e-01f, -3.00741700e-01f, -2.98882200e-01f, -2.97004057e-01f, -2.95107490e-01f, - -2.93192571e-01f, -2.91259453e-01f, -2.89308385e-01f, -2.87339400e-01f, -2.85352731e-01f, -2.83348484e-01f, - -2.81326751e-01f, -2.79287771e-01f, -2.77231627e-01f, -2.75158593e-01f, -2.73068673e-01f, -2.70962077e-01f, - -2.68838998e-01f, -2.66699597e-01f, -2.64543919e-01f, -2.62372258e-01f, -2.60184687e-01f, -2.57981453e-01f, - -2.55762621e-01f, -2.53528435e-01f, -2.51279079e-01f, -2.49014668e-01f, -2.46735349e-01f, -2.44441307e-01f, - -2.42132726e-01f, -2.39809846e-01f, -2.37472739e-01f, -2.35121540e-01f, -2.32756549e-01f, -2.30377876e-01f, - -2.27985684e-01f, -2.25580182e-01f, -2.23161532e-01f, -2.20729936e-01f, -2.18285516e-01f, -2.15828528e-01f, - -2.13359121e-01f, -2.10877473e-01f, -2.08383797e-01f, -2.05878130e-01f, -2.03360876e-01f, -2.00832099e-01f, - -1.98292012e-01f, -1.95740791e-01f, -1.93178672e-01f, -1.90605771e-01f, -1.88022325e-01f, -1.85428542e-01f, - -1.82824527e-01f, -1.80210592e-01f, -1.77586867e-01f, -1.74953539e-01f, -1.72310749e-01f, -1.69658801e-01f, - -1.66997814e-01f, -1.64327989e-01f, -1.61649588e-01f, -1.58962786e-01f, -1.56267775e-01f, -1.53564734e-01f, - -1.50853818e-01f, -1.48135307e-01f, -1.45409451e-01f, -1.42676338e-01f, -1.39936207e-01f, -1.37189239e-01f, - -1.34435680e-01f, -1.31675715e-01f, -1.28909524e-01f, -1.26137364e-01f, -1.23359369e-01f, -1.20575779e-01f, - -1.17786863e-01f, -1.14992751e-01f, -1.12193672e-01f, -1.09389770e-01f, -1.06581400e-01f, -1.03768617e-01f, - -1.00951692e-01f, -9.81308589e-02f, -9.53063402e-02f, -9.24782511e-02f, -8.96468725e-02f, -8.68122849e-02f, - -8.39749530e-02f, -8.11348790e-02f, -7.82923730e-02f, -7.54475481e-02f, -7.26006970e-02f, -6.97520165e-02f, - -6.69016795e-02f, -6.40499264e-02f, -6.11970029e-02f, -5.83430882e-02f, -5.54883436e-02f, -5.26330206e-02f, - -4.97773054e-02f, -4.69215398e-02f, -4.40657494e-02f, -4.12102104e-02f, -3.83551376e-02f, -3.55007936e-02f, - -3.26473384e-02f, -2.97950101e-02f, -2.69439912e-02f, -2.40945075e-02f, -2.12467160e-02f, -1.84009756e-02f, - -1.55573052e-02f, -1.27160420e-02f, -9.87733696e-03f, -7.04144838e-03f, -4.20859203e-03f, -1.37885803e-03f, - 1.44737047e-03f, 4.27004411e-03f, 7.08882719e-03f, 9.90366357e-03f, 1.27141114e-02f, 1.55202571e-02f, - 1.83216331e-02f, 2.11181617e-02f, 2.39096668e-02f, 2.66957849e-02f, 2.94765253e-02f, 3.22514806e-02f, - 3.50205957e-02f, 3.77835565e-02f, 4.05402501e-02f, 4.32904120e-02f, 4.60338912e-02f, 4.87704209e-02f, - 5.14998721e-02f, 5.42219632e-02f, 5.69365884e-02f, 5.96434910e-02f, 6.23424651e-02f, 6.50333211e-02f, - 6.77158702e-02f, 7.03899565e-02f, 7.30552323e-02f, 7.57116381e-02f, 7.83589757e-02f, 8.09970020e-02f, - 8.36255415e-02f, 8.62444034e-02f, 8.88533645e-02f, 9.14522956e-02f, 9.40409909e-02f, 9.66192257e-02f, - 9.91867792e-02f, 1.01743576e-01f, 1.04289297e-01f, 1.06823909e-01f, 1.09347014e-01f, 1.11858685e-01f, - 1.14358540e-01f, 1.16846404e-01f, 1.19322201e-01f, 1.21785664e-01f, 1.24236622e-01f, 1.26674977e-01f, - 1.29100503e-01f, 1.31513034e-01f, 1.33912298e-01f, 1.36298272e-01f, 1.38670572e-01f, 1.41029261e-01f, - 1.43374073e-01f, 1.45704785e-01f, 1.48021299e-01f, 1.50323344e-01f, 1.52610896e-01f, 1.54883691e-01f, - 1.57141596e-01f, 1.59384418e-01f, 1.61612032e-01f, 1.63824293e-01f, 1.66020909e-01f, 1.68201890e-01f, - 1.70366958e-01f, 1.72516081e-01f, 1.74648950e-01f, 1.76765527e-01f, 1.78865600e-01f, 1.80948982e-01f, - 1.83015685e-01f, 1.85065412e-01f, 1.87097972e-01f, 1.89113349e-01f, 1.91111327e-01f, 1.93091893e-01f, - 1.95054698e-01f, 1.96999715e-01f, 1.98926785e-01f, 2.00835732e-01f, 2.02726547e-01f, 2.04598940e-01f, - 2.06452841e-01f, 2.08288151e-01f, 2.10104703e-01f, 2.11902364e-01f, 2.13680960e-01f, 2.15440476e-01f, - 2.17180746e-01f, 2.18901579e-01f, 2.20603019e-01f, 2.22284679e-01f, 2.23946694e-01f, 2.25588773e-01f, - 2.27210898e-01f, 2.28812942e-01f, 2.30394827e-01f, 2.31956352e-01f, 2.33497362e-01f, 2.35017968e-01f, - 2.36517831e-01f, 2.37997015e-01f, 2.39455357e-01f, 2.40892785e-01f, 2.42309096e-01f, 2.43704265e-01f, - 2.45078220e-01f, 2.46430848e-01f, 2.47762035e-01f, 2.49071644e-01f, 2.50359698e-01f, 2.51626084e-01f, - 2.52870615e-01f, 2.54093341e-01f, 2.55294108e-01f, 2.56472852e-01f, 2.57629500e-01f, 2.58763948e-01f, - 2.59876133e-01f, 2.60966001e-01f, 2.62033455e-01f, 2.63078427e-01f, 2.64100872e-01f, 2.65100674e-01f, - 2.66077909e-01f, 2.67032266e-01f, 2.67963945e-01f, 2.68872714e-01f, 2.69758570e-01f, 2.70621496e-01f, - 2.71461368e-01f, 2.72278196e-01f, 2.73071886e-01f, 2.73842387e-01f, 2.74589729e-01f, 2.75313797e-01f, - 2.76014533e-01f, 2.76691946e-01f, 2.77346015e-01f, 2.77976617e-01f, 2.78583817e-01f, 2.79167518e-01f, - 2.79727686e-01f, 2.80264322e-01f, 2.80777417e-01f, 2.81266855e-01f, 2.81732698e-01f, 2.82174979e-01f, - 2.82593499e-01f, 2.82988439e-01f, 2.83359584e-01f, 2.83707094e-01f, 2.84030859e-01f, 2.84330916e-01f, - 2.84607242e-01f, 2.84859824e-01f, 2.85088662e-01f, 2.85293749e-01f, 2.85475102e-01f, 2.85632712e-01f, - 2.85766540e-01f, 2.85876695e-01f, 2.85963088e-01f, 2.86025797e-01f, 2.86064750e-01f, 2.86080019e-01f, - 2.86071641e-01f, 2.86039602e-01f, 2.85983883e-01f, 2.85904595e-01f, 2.85801667e-01f, 2.85675228e-01f, - 2.85525131e-01f, 2.85351560e-01f, 2.85154552e-01f, 2.84934050e-01f, 2.84690161e-01f, 2.84422893e-01f, - 2.84132260e-01f, 2.83818296e-01f, 2.83481068e-01f, 2.83120639e-01f, 2.82737013e-01f, 2.82330279e-01f, - 2.81900541e-01f, 2.81447660e-01f, 2.80971876e-01f, 2.80473140e-01f, 2.79951562e-01f, 2.79407164e-01f, - 2.78840077e-01f, 2.78250270e-01f, 2.77637904e-01f, 2.77002907e-01f, 2.76345509e-01f, 2.75665669e-01f, - 2.74963514e-01f, 2.74239056e-01f, 2.73492452e-01f, 2.72723721e-01f, 2.71932955e-01f, 2.71120230e-01f, - 2.70285684e-01f, 2.69429303e-01f, 2.68551259e-01f, 2.67651586e-01f, 2.66730397e-01f, 2.65787787e-01f, - 2.64823839e-01f, 2.63838701e-01f, 2.62832333e-01f, 2.61804964e-01f, 2.60756656e-01f, 2.59687544e-01f, - 2.58597668e-01f, 2.57487123e-01f, 2.56356094e-01f, 2.55204621e-01f, 2.54032859e-01f, 2.52840892e-01f, - 2.51628858e-01f, 2.50396836e-01f, 2.49145025e-01f, 2.47873432e-01f, 2.46582260e-01f, 2.45271602e-01f, - 2.43941550e-01f, 2.42592233e-01f, 2.41223901e-01f, 2.39836493e-01f, 2.38430264e-01f, 2.37005336e-01f, - 2.35561786e-01f, 2.34099784e-01f, 2.32619489e-01f, 2.31120988e-01f, 2.29604432e-01f, 2.28070030e-01f, - 2.26517765e-01f, 2.24948005e-01f, 2.23360661e-01f, 2.21756023e-01f, 2.20134209e-01f, 2.18495400e-01f, - 2.16839686e-01f, 2.15167214e-01f, 2.13478168e-01f, 2.11772713e-01f, 2.10051008e-01f, 2.08313159e-01f, - 2.06559370e-01f, 2.04789809e-01f, 2.03004614e-01f, 2.01203934e-01f, 1.99387966e-01f, 1.97556774e-01f, - 1.95710716e-01f, 1.93849796e-01f, 1.91974253e-01f, 1.90084229e-01f, 1.88179915e-01f, 1.86261480e-01f, - 1.84329074e-01f, 1.82382873e-01f, 1.80423040e-01f, 1.78449882e-01f, 1.76463414e-01f, 1.74463859e-01f, - 1.72451393e-01f, 1.70426250e-01f, 1.68388609e-01f, 1.66338525e-01f, 1.64276319e-01f, 1.62202105e-01f, - 1.60116152e-01f, 1.58018616e-01f, 1.55909584e-01f, 1.53789286e-01f, 1.51658043e-01f, 1.49515869e-01f, - 1.47363108e-01f, 1.45199819e-01f, 1.43026288e-01f, 1.40842649e-01f, 1.38649125e-01f, 1.36445886e-01f, - 1.34233135e-01f, 1.32011120e-01f, 1.29779999e-01f, 1.27539954e-01f, 1.25291182e-01f, 1.23033970e-01f, - 1.20768404e-01f, 1.18494681e-01f, 1.16213098e-01f, 1.13923814e-01f, 1.11627090e-01f, 1.09322938e-01f, - 1.07011778e-01f, 1.04693651e-01f, 1.02368906e-01f, 1.00037642e-01f, 9.77001128e-02f, 9.53565434e-02f, - 9.30070937e-02f, 9.06520030e-02f, 8.82914334e-02f, 8.59256284e-02f, 8.35547856e-02f, 8.11791026e-02f, - 7.87988940e-02f, 7.64142408e-02f, 7.40253455e-02f, 7.16325101e-02f, 6.92358550e-02f, 6.68357023e-02f, - 6.44321262e-02f, 6.20254768e-02f, 5.96158621e-02f, 5.72035328e-02f, 5.47886826e-02f, 5.23715331e-02f, - 4.99523754e-02f, 4.75312335e-02f, 4.51084965e-02f, 4.26843332e-02f, 4.02588192e-02f, 3.78324165e-02f, - 3.54051102e-02f, 3.29772951e-02f, 3.05490278e-02f, 2.81205746e-02f, 2.56922040e-02f, 2.32640574e-02f, - 2.08364261e-02f, 1.84093907e-02f, 1.59832525e-02f, 1.35582116e-02f, 1.11345293e-02f, 8.71234648e-03f, - 6.29183524e-03f, 3.87331920e-03f, 1.45694861e-03f, -9.57073660e-04f, -3.36848523e-03f, -5.77716955e-03f, - -8.18285575e-03f, -1.05852906e-02f, -1.29843812e-02f, -1.53798076e-02f, -1.77713850e-02f, -2.01589899e-02f, - -2.25423335e-02f, -2.49212646e-02f, -2.72954921e-02f, -2.96649184e-02f, -3.20292099e-02f, -3.43882419e-02f, - -3.67418117e-02f, -3.90897885e-02f, -4.14318196e-02f, -4.37677543e-02f, -4.60973883e-02f, -4.84205952e-02f, - -5.07371063e-02f, -5.30467100e-02f, -5.53492067e-02f, -5.76444780e-02f, -5.99322309e-02f, -6.22123297e-02f, - -6.44845179e-02f, -6.67486796e-02f, -6.90045169e-02f, -7.12519770e-02f, -7.34907487e-02f, -7.57206511e-02f, - -7.79415119e-02f, -8.01531890e-02f, -8.23554532e-02f, -8.45481099e-02f, -8.67308976e-02f, -8.89037767e-02f, - -9.10664546e-02f, -9.32188278e-02f, -9.53606755e-02f, -9.74917114e-02f, -9.96119143e-02f, -1.01721057e-01f, - -1.03818865e-01f, -1.05905248e-01f, -1.07980077e-01f, -1.10043046e-01f, -1.12094128e-01f, -1.14133000e-01f, - -1.16159568e-01f, -1.18173580e-01f, -1.20175006e-01f, -1.22163537e-01f, -1.24139177e-01f, -1.26101584e-01f, - -1.28050644e-01f, -1.29986176e-01f, -1.31908076e-01f, -1.33816166e-01f, -1.35710250e-01f, -1.37590202e-01f, - -1.39455856e-01f, -1.41307049e-01f, -1.43143614e-01f, -1.44965422e-01f, -1.46772228e-01f, -1.48563997e-01f, - -1.50340572e-01f, -1.52101785e-01f, -1.53847427e-01f, -1.55577414e-01f, -1.57291572e-01f, -1.58989773e-01f, - -1.60671930e-01f, -1.62337758e-01f, -1.63987236e-01f, -1.65620242e-01f, -1.67236575e-01f, -1.68836167e-01f, - -1.70418739e-01f, -1.71984290e-01f, -1.73532720e-01f, -1.75063804e-01f, -1.76577517e-01f, -1.78073596e-01f, - -1.79552037e-01f, -1.81012676e-01f, -1.82455384e-01f, -1.83879990e-01f, -1.85286498e-01f, -1.86674809e-01f, - -1.88044676e-01f, -1.89396048e-01f, -1.90728814e-01f, -1.92042884e-01f, -1.93338160e-01f, -1.94614467e-01f, - -1.95871777e-01f, -1.97109986e-01f, -1.98328971e-01f, -1.99528633e-01f, -2.00708864e-01f, -2.01869538e-01f, - -2.03010625e-01f, -2.04132066e-01f, -2.05233726e-01f, -2.06315517e-01f, -2.07377424e-01f, -2.08419160e-01f, - -2.09440897e-01f, -2.10442343e-01f, -2.11423600e-01f, -2.12384517e-01f, -2.13325020e-01f, -2.14244969e-01f, - -2.15144362e-01f, -2.16023185e-01f, -2.16881292e-01f, -2.17718608e-01f, -2.18535178e-01f, -2.19330740e-01f, - -2.20105487e-01f, -2.20859169e-01f, -2.21591851e-01f, -2.22303414e-01f, -2.22993850e-01f, -2.23663082e-01f, - -2.24311009e-01f, -2.24937693e-01f, -2.25543001e-01f, -2.26126978e-01f, -2.26689512e-01f, -2.27230679e-01f, - -2.27750237e-01f, -2.28248397e-01f, -2.28724887e-01f, -2.29179861e-01f, -2.29613257e-01f, -2.30025006e-01f, - -2.30415087e-01f, -2.30783513e-01f, -2.31130237e-01f, -2.31455227e-01f, -2.31758489e-01f, -2.32040063e-01f, - -2.32299860e-01f, -2.32537908e-01f, -2.32754200e-01f, -2.32948714e-01f, -2.33121449e-01f, -2.33272422e-01f, - -2.33401627e-01f, -2.33509045e-01f, -2.33594655e-01f, -2.33658605e-01f, -2.33700765e-01f, -2.33721199e-01f, - -2.33719861e-01f, -2.33696831e-01f, -2.33652096e-01f, -2.33585771e-01f, -2.33497737e-01f, -2.33388074e-01f, - -2.33256804e-01f, -2.33103956e-01f, -2.32929530e-01f, -2.32733673e-01f, -2.32516237e-01f, -2.32277400e-01f, - -2.32017131e-01f, -2.31735510e-01f, -2.31432523e-01f, -2.31108234e-01f, -2.30762734e-01f, -2.30396045e-01f, - -2.30008156e-01f, -2.29599210e-01f, -2.29169158e-01f, -2.28718175e-01f, -2.28246195e-01f, -2.27753383e-01f, - -2.27239710e-01f, -2.26705241e-01f, -2.26150215e-01f, -2.25574381e-01f, -2.24978160e-01f, -2.24361287e-01f, - -2.23724131e-01f, -2.23066499e-01f, -2.22388697e-01f, -2.21690635e-01f, -2.20972473e-01f, -2.20234253e-01f, - -2.19476129e-01f, -2.18698087e-01f, -2.17900238e-01f, -2.17082728e-01f, -2.16245640e-01f, -2.15388985e-01f, - -2.14512917e-01f, -2.13617522e-01f, -2.12702910e-01f, -2.11769182e-01f, -2.10816324e-01f, -2.09844635e-01f, - -2.08854079e-01f, -2.07844800e-01f, -2.06816908e-01f, -2.05770507e-01f, -2.04705741e-01f, -2.03622630e-01f, - -2.02521364e-01f, -2.01402103e-01f, -2.00264837e-01f, -1.99109776e-01f, -1.97936996e-01f, -1.96746663e-01f, - -1.95538852e-01f, -1.94313732e-01f, -1.93071365e-01f, -1.91811975e-01f, -1.90535643e-01f, -1.89242467e-01f, - -1.87932610e-01f, -1.86606212e-01f, -1.85263356e-01f, -1.83904316e-01f, -1.82529106e-01f, -1.81137899e-01f, - -1.79730798e-01f, -1.78308054e-01f, -1.76869711e-01f, -1.75415924e-01f, -1.73946900e-01f, -1.72462756e-01f, - -1.70963623e-01f, -1.69449669e-01f, -1.67920957e-01f, -1.66377857e-01f, -1.64820315e-01f, -1.63248636e-01f, - -1.61662843e-01f, -1.60063204e-01f, -1.58449812e-01f, -1.56822866e-01f, -1.55182501e-01f, -1.53528918e-01f, - -1.51862312e-01f, -1.50182659e-01f, -1.48490381e-01f, -1.46785490e-01f, -1.45068177e-01f, -1.43338628e-01f, - -1.41597051e-01f, -1.39843570e-01f, -1.38078415e-01f, -1.36301635e-01f, -1.34513593e-01f, -1.32714274e-01f, - -1.30903986e-01f, -1.29082858e-01f, -1.27251137e-01f, -1.25408873e-01f, -1.23556347e-01f, -1.21693718e-01f, - -1.19821143e-01f, -1.17938889e-01f, -1.16047018e-01f, -1.14145843e-01f, -1.12235471e-01f, -1.10316091e-01f, - -1.08387927e-01f, -1.06451124e-01f, -1.04505940e-01f, -1.02552475e-01f, -1.00590991e-01f, -9.86216287e-02f, - -9.66446561e-02f, -9.46601599e-02f, -9.26684360e-02f, -9.06696156e-02f, -8.86639674e-02f, -8.66516170e-02f, - -8.46327574e-02f, -8.26076038e-02f, -8.05763090e-02f, -7.85392502e-02f, -7.64963470e-02f, -7.44480477e-02f, - -7.23943723e-02f, -7.03356706e-02f, -6.82720171e-02f, -6.62036804e-02f, -6.41307777e-02f, -6.20536784e-02f, - -5.99724409e-02f, -5.78872736e-02f, -5.57984877e-02f, -5.37061515e-02f, -5.16105651e-02f, -4.95118163e-02f, - -4.74102328e-02f, -4.53059773e-02f, -4.31992719e-02f, -4.10902410e-02f, -3.89791506e-02f, -3.68662096e-02f, - -3.47515774e-02f, -3.26355244e-02f, -3.05181839e-02f, -2.83998154e-02f, -2.62806086e-02f, -2.41606997e-02f, - -2.20403928e-02f, -1.99198563e-02f, -1.77992749e-02f, -1.56788312e-02f, -1.35588308e-02f, -1.14394065e-02f, - -9.32068351e-03f, -7.20301575e-03f, -5.08650203e-03f, -2.97139242e-03f, -8.57884815e-04f, 1.25385428e-03f, - 3.36354685e-03f, 5.47109234e-03f, 7.57619970e-03f, 9.67872126e-03f, 1.17784345e-02f, 1.38751450e-02f, - 1.59686728e-02f, 1.80587938e-02f, 2.01452921e-02f, 2.22279358e-02f, 2.43066920e-02f, 2.63811823e-02f, - 2.84512849e-02f, 3.05168384e-02f, 3.25775830e-02f, 3.46332810e-02f, 3.66838589e-02f, 3.87290041e-02f, - 4.07686819e-02f, 4.28025729e-02f, 4.48304810e-02f, 4.68521979e-02f, 4.88676301e-02f, 5.08765549e-02f, - 5.28786842e-02f, 5.48739856e-02f, 5.68621222e-02f, 5.88430367e-02f, 6.08164513e-02f, 6.27822259e-02f, - 6.47401025e-02f, 6.66899925e-02f, 6.86317160e-02f, 7.05649503e-02f, 7.24896450e-02f, 7.44055762e-02f, - 7.63125763e-02f, 7.82104959e-02f, 8.00990763e-02f, 8.19781894e-02f, 8.38476508e-02f, 8.57073051e-02f, - 8.75569467e-02f, 8.93964285e-02f, 9.12255341e-02f, 9.30441393e-02f, 9.48520852e-02f, 9.66491916e-02f, - 9.84352313e-02f, 1.00210094e-01f, 1.01973618e-01f, 1.03725603e-01f, 1.05465932e-01f, 1.07194389e-01f, - 1.08910876e-01f, 1.10615175e-01f, 1.12307185e-01f, 1.13986681e-01f, 1.15653533e-01f, 1.17307669e-01f, - 1.18948805e-01f, 1.20576870e-01f, 1.22191670e-01f, 1.23793088e-01f, 1.25380991e-01f, 1.26955187e-01f, - 1.28515555e-01f, 1.30061955e-01f, 1.31594299e-01f, 1.33112261e-01f, 1.34615948e-01f, 1.36105013e-01f, - 1.37579476e-01f, 1.39039087e-01f, 1.40483764e-01f, 1.41913430e-01f, 1.43327864e-01f, 1.44726935e-01f, - 1.46110624e-01f, 1.47478701e-01f, 1.48831051e-01f, 1.50167588e-01f, 1.51488230e-01f, 1.52792706e-01f, - 1.54081101e-01f, 1.55353157e-01f, 1.56608808e-01f, 1.57847922e-01f, 1.59070398e-01f, 1.60276147e-01f, - 1.61465050e-01f, 1.62636981e-01f, 1.63791824e-01f, 1.64929533e-01f, 1.66050000e-01f, 1.67153103e-01f, - 1.68238699e-01f, 1.69306821e-01f, 1.70357165e-01f, 1.71389871e-01f, 1.72404705e-01f, 1.73401624e-01f, - 1.74380550e-01f, 1.75341388e-01f, 1.76284039e-01f, 1.77208464e-01f, 1.78114524e-01f, 1.79002166e-01f, - 1.79871290e-01f, 1.80721932e-01f, 1.81553892e-01f, 1.82367232e-01f, 1.83161672e-01f, 1.83937409e-01f, - 1.84694147e-01f, 1.85431946e-01f, 1.86150744e-01f, 1.86850448e-01f, 1.87531002e-01f, 1.88192389e-01f, - 1.88834515e-01f, 1.89457330e-01f, 1.90060809e-01f, 1.90644931e-01f, 1.91209552e-01f, 1.91754740e-01f, - 1.92280376e-01f, 1.92786472e-01f, 1.93273005e-01f, 1.93739833e-01f, 1.94187026e-01f, 1.94614460e-01f, - 1.95022218e-01f, 1.95410185e-01f, 1.95778460e-01f, 1.96126840e-01f, 1.96455424e-01f, 1.96764141e-01f, - 1.97053015e-01f, 1.97322024e-01f, 1.97571067e-01f, 1.97800248e-01f, 1.98009540e-01f, 1.98198856e-01f, - 1.98368270e-01f, 1.98517749e-01f, 1.98647247e-01f, 1.98756884e-01f, 1.98846541e-01f, 1.98916256e-01f, - 1.98966060e-01f, 1.98995961e-01f, 1.99005930e-01f, 1.98996021e-01f, 1.98966263e-01f, 1.98916605e-01f, - 1.98847035e-01f, 1.98757691e-01f, 1.98648576e-01f, 1.98519642e-01f, 1.98370948e-01f, 1.98202558e-01f, - 1.98014401e-01f, 1.97806653e-01f, 1.97579224e-01f, 1.97332173e-01f, 1.97065602e-01f, 1.96779507e-01f, - 1.96473944e-01f, 1.96148904e-01f, 1.95804488e-01f, 1.95440671e-01f, 1.95057609e-01f, 1.94655302e-01f, - 1.94233763e-01f, 1.93793133e-01f, 1.93333312e-01f, 1.92854597e-01f, 1.92356822e-01f, 1.91840216e-01f, - 1.91304718e-01f, 1.90750406e-01f, 1.90177470e-01f, 1.89585896e-01f, 1.88975697e-01f, 1.88346973e-01f, - 1.87699879e-01f, 1.87034498e-01f, 1.86350761e-01f, 1.85648886e-01f, 1.84928877e-01f, 1.84190848e-01f, - 1.83434925e-01f, 1.82661116e-01f, 1.81869592e-01f, 1.81060352e-01f, 1.80233559e-01f, 1.79389314e-01f, - 1.78527656e-01f, 1.77648709e-01f, 1.76752511e-01f, 1.75839294e-01f, 1.74909151e-01f, 1.73962035e-01f, - 1.72998204e-01f, 1.72017622e-01f, 1.71020593e-01f, 1.70007036e-01f, 1.68977165e-01f, 1.67931053e-01f, - 1.66868887e-01f, 1.65790776e-01f, 1.64696649e-01f, 1.63586902e-01f, 1.62461413e-01f, 1.61320526e-01f, - 1.60164205e-01f, 1.58992644e-01f, 1.57805938e-01f, 1.56604268e-01f, 1.55387702e-01f, 1.54156458e-01f, - 1.52910539e-01f, 1.51650221e-01f, 1.50375541e-01f, 1.49086678e-01f, 1.47783716e-01f, 1.46466865e-01f, - 1.45136227e-01f, 1.43792025e-01f, 1.42434310e-01f, 1.41063244e-01f, 1.39678990e-01f, 1.38281727e-01f, - 1.36871522e-01f, 1.35448608e-01f, 1.34013049e-01f, 1.32565130e-01f, 1.31104859e-01f, 1.29632516e-01f, - 1.28148111e-01f, 1.26651985e-01f, 1.25144152e-01f, 1.23624869e-01f, 1.22094227e-01f, 1.20552394e-01f, - 1.18999559e-01f, 1.17435871e-01f, 1.15861563e-01f, 1.14276688e-01f, 1.12681469e-01f, 1.11076055e-01f, - 1.09460624e-01f, 1.07835401e-01f, 1.06200512e-01f, 1.04556086e-01f, 1.02902330e-01f, 1.01239477e-01f, - 9.95676279e-02f, 9.78869417e-02f, 9.61976458e-02f, 9.44998932e-02f, 9.27939255e-02f, 9.10798016e-02f, - 8.93577933e-02f, 8.76280467e-02f, 8.58907625e-02f, 8.41460344e-02f, 8.23942547e-02f, 8.06353117e-02f, - 7.88696968e-02f, 7.70973484e-02f, 7.53185545e-02f, 7.35334702e-02f, 7.17423136e-02f, 6.99452839e-02f, - 6.81425611e-02f, 6.63342465e-02f, 6.45206646e-02f, 6.27018525e-02f, 6.08781576e-02f, 5.90495832e-02f, - 5.72165765e-02f, 5.53790776e-02f, 5.35373940e-02f, 5.16916683e-02f, 4.98421291e-02f, 4.79889847e-02f, - 4.61323878e-02f, 4.42725547e-02f, 4.24096156e-02f, 4.05438837e-02f, 3.86754092e-02f, 3.68044652e-02f, - 3.49312358e-02f, 3.30559198e-02f, 3.11787544e-02f, 2.92997719e-02f, 2.74193684e-02f, 2.55375740e-02f, - 2.36546700e-02f, 2.17708403e-02f, 1.98862372e-02f, 1.80010835e-02f, 1.61155788e-02f, 1.42299283e-02f, - 1.23442904e-02f, 1.04588609e-02f, 8.57385105e-03f, 6.68942186e-03f, 4.80579148e-03f, 2.92323436e-03f, - 1.04172294e-03f, -8.38261980e-04f, -2.71684022e-03f, -4.59355348e-03f, -6.46835136e-03f, -8.34104098e-03f, - -1.02113187e-02f, -1.20791442e-02f, -1.39442602e-02f, -1.58064600e-02f, -1.76656172e-02f, -1.95214145e-02f, - -2.13738098e-02f, -2.32224962e-02f, -2.50674407e-02f, -2.69082929e-02f, -2.87449265e-02f, -3.05771257e-02f, - -3.24047872e-02f, -3.42277271e-02f, -3.60456332e-02f, -3.78584913e-02f, -3.96659087e-02f, -4.14679093e-02f, - -4.32642157e-02f, -4.50546425e-02f, -4.68390389e-02f, -4.86171523e-02f, -5.03889263e-02f, -5.21541036e-02f, - -5.39124824e-02f, -5.56639922e-02f, -5.74083015e-02f, -5.91454172e-02f, -6.08749878e-02f, -6.25969749e-02f, - -6.43111015e-02f, -6.60173726e-02f, -6.77153146e-02f, -6.94050540e-02f, -7.10862670e-02f, -7.27588455e-02f, - -7.44226007e-02f, -7.60773137e-02f, -7.77228948e-02f, -7.93591511e-02f, -8.09859682e-02f, -8.26031105e-02f, - -8.42104279e-02f, -8.58078240e-02f, -8.73950448e-02f, -8.89720003e-02f, -9.05385104e-02f, -9.20944589e-02f, - -9.36396586e-02f, -9.51739235e-02f, -9.66971351e-02f, -9.82091977e-02f, -9.97098794e-02f, -1.01199052e-01f, - -1.02676549e-01f, -1.04142275e-01f, -1.05596111e-01f, -1.07037772e-01f, -1.08467296e-01f, -1.09884430e-01f, - -1.11289034e-01f, -1.12681054e-01f, -1.14060209e-01f, -1.15426538e-01f, -1.16779788e-01f, -1.18119886e-01f, - -1.19446681e-01f, -1.20760003e-01f, -1.22059780e-01f, -1.23345860e-01f, -1.24618162e-01f, -1.25876449e-01f, - -1.27120754e-01f, -1.28350844e-01f, -1.29566619e-01f, -1.30767994e-01f, -1.31954858e-01f, -1.33127071e-01f, - -1.34284493e-01f, -1.35427053e-01f, -1.36554614e-01f, -1.37667141e-01f, -1.38764471e-01f, -1.39846447e-01f, - -1.40913084e-01f, -1.41964138e-01f, -1.42999663e-01f, -1.44019493e-01f, -1.45023462e-01f, -1.46011587e-01f, - -1.46983735e-01f, -1.47939751e-01f, -1.48879632e-01f, -1.49803251e-01f, -1.50710563e-01f, -1.51601483e-01f, - -1.52475766e-01f, -1.53333561e-01f, -1.54174628e-01f, -1.54999026e-01f, -1.55806568e-01f, -1.56597227e-01f, - -1.57370922e-01f, -1.58127533e-01f, -1.58867116e-01f, -1.59589427e-01f, -1.60294599e-01f, -1.60982462e-01f, - -1.61652929e-01f, -1.62305967e-01f, -1.62941560e-01f, -1.63559605e-01f, -1.64160078e-01f, -1.64742863e-01f, - -1.65308054e-01f, -1.65855433e-01f, -1.66385077e-01f, -1.66896830e-01f, -1.67390780e-01f, -1.67866801e-01f, - -1.68324861e-01f, -1.68764906e-01f, -1.69186979e-01f, -1.69591004e-01f, -1.69976941e-01f, -1.70344724e-01f, - -1.70694360e-01f, -1.71025854e-01f, -1.71339161e-01f, -1.71634253e-01f, -1.71911096e-01f, -1.72169725e-01f, - -1.72410027e-01f, -1.72632115e-01f, -1.72835853e-01f, -1.73021334e-01f, -1.73188439e-01f, -1.73337302e-01f, - -1.73467815e-01f, -1.73580015e-01f, -1.73673868e-01f, -1.73749360e-01f, -1.73806613e-01f, -1.73845481e-01f, - -1.73866056e-01f, -1.73868354e-01f, -1.73852355e-01f, -1.73818057e-01f, -1.73765544e-01f, -1.73694737e-01f, - -1.73605731e-01f, -1.73498489e-01f, -1.73373090e-01f, -1.73229532e-01f, -1.73067837e-01f, -1.72888006e-01f, - -1.72690137e-01f, -1.72474205e-01f, -1.72240252e-01f, -1.71988312e-01f, -1.71718488e-01f, -1.71430732e-01f, - -1.71125123e-01f, -1.70801703e-01f, -1.70460458e-01f, -1.70101559e-01f, -1.69724923e-01f, -1.69330727e-01f, - -1.68918914e-01f, -1.68489636e-01f, -1.68042787e-01f, -1.67578633e-01f, -1.67097108e-01f, -1.66598235e-01f, - -1.66082222e-01f, -1.65549022e-01f, -1.64998735e-01f, -1.64431426e-01f, -1.63847076e-01f, -1.63245951e-01f, - -1.62627971e-01f, -1.61993270e-01f, -1.61341942e-01f, -1.60673949e-01f, -1.59989561e-01f, -1.59288716e-01f, - -1.58571497e-01f, -1.57838066e-01f, -1.57088502e-01f, -1.56322859e-01f, -1.55541232e-01f, -1.54743675e-01f, - -1.53930338e-01f, -1.53101334e-01f, -1.52256696e-01f, -1.51396569e-01f, -1.50521048e-01f, -1.49630175e-01f, - -1.48724228e-01f, -1.47803058e-01f, -1.46866933e-01f, -1.45915940e-01f, -1.44950144e-01f, -1.43969746e-01f, - -1.42974793e-01f, -1.41965365e-01f, -1.40941600e-01f, -1.39903745e-01f, -1.38851691e-01f, -1.37785737e-01f, - -1.36705942e-01f, -1.35612351e-01f, -1.34505242e-01f, -1.33384656e-01f, -1.32250694e-01f, -1.31103535e-01f, - -1.29943260e-01f, -1.28770074e-01f, -1.27584048e-01f, -1.26385298e-01f, -1.25174054e-01f, -1.23950314e-01f, - -1.22714364e-01f, -1.21466226e-01f, -1.20206125e-01f, -1.18934090e-01f, -1.17650376e-01f, -1.16355057e-01f, - -1.15048340e-01f, -1.13730277e-01f, -1.12401133e-01f, -1.11060953e-01f, -1.09709913e-01f, -1.08348219e-01f, - -1.06975915e-01f, -1.05593271e-01f, -1.04200392e-01f, -1.02797370e-01f, -1.01384496e-01f, -9.99617377e-02f, - -9.85294400e-02f, -9.70876496e-02f, -9.56365842e-02f, -9.41763226e-02f, -9.27070804e-02f, -9.12290864e-02f, - -8.97423740e-02f, -8.82471679e-02f, -8.67436631e-02f, -8.52319471e-02f, -8.37122718e-02f, -8.21847175e-02f, - -8.06495130e-02f, -7.91067680e-02f, -7.75567636e-02f, -7.59995746e-02f, -7.44353329e-02f, -7.28643398e-02f, - -7.12866786e-02f, -6.97025295e-02f, -6.81120811e-02f, -6.65154550e-02f, -6.49129251e-02f, -6.33046155e-02f, - -6.16906700e-02f, -6.00712678e-02f, -5.84466154e-02f, -5.68169551e-02f, -5.51822891e-02f, -5.35429096e-02f, - -5.18989745e-02f, -5.02507146e-02f, -4.85982584e-02f, -4.69417513e-02f, -4.52813960e-02f, -4.36174042e-02f, - -4.19499038e-02f, -4.02791405e-02f, -3.86052291e-02f, -3.69284156e-02f, -3.52488305e-02f, -3.35666756e-02f, - -3.18821334e-02f, -3.01953085e-02f, -2.85065561e-02f, -2.68158418e-02f, -2.51235658e-02f, -2.34297232e-02f, - -2.17345791e-02f, -2.00383870e-02f, -1.83412071e-02f, -1.66432521e-02f, -1.49447262e-02f, -1.32457726e-02f, - -1.15467070e-02f, -9.84751499e-03f, -8.14850150e-03f, -6.44986286e-03f, -4.75168950e-03f, -3.05420080e-03f, - -1.35762100e-03f, 3.37941652e-04f, 2.03222831e-03f, 3.72510496e-03f, 5.41637088e-03f, 7.10586089e-03f, - 8.79342780e-03f, 1.04788095e-02f, 1.21618635e-02f, 1.38424679e-02f, 1.55203645e-02f, 1.71954243e-02f, - 1.88674255e-02f, 2.05362265e-02f, 2.22016553e-02f, 2.38635216e-02f, 2.55216241e-02f, 2.71758242e-02f, - 2.88259359e-02f, 3.04718280e-02f, 3.21131635e-02f, 3.37499981e-02f, 3.53819635e-02f, 3.70090687e-02f, - 3.86309477e-02f, 4.02475616e-02f, 4.18586916e-02f, 4.34641762e-02f, 4.50639021e-02f, 4.66575992e-02f, - 4.82452000e-02f, 4.98263813e-02f, 5.14012020e-02f, 5.29692621e-02f, 5.45306315e-02f, 5.60849229e-02f, - 5.76321302e-02f, 5.91720225e-02f, 6.07044421e-02f, 6.22292398e-02f, 6.37462993e-02f, 6.52553919e-02f, - 6.67563750e-02f, 6.82490948e-02f, 6.97334449e-02f, 7.12091825e-02f, 7.26762565e-02f, 7.41343758e-02f, - 7.55835274e-02f, 7.70235283e-02f, 7.84541459e-02f, 7.98753198e-02f, 8.12868577e-02f, 8.26886481e-02f, - 8.40805272e-02f, 8.54623177e-02f, 8.68338807e-02f, 8.81951796e-02f, 8.95459493e-02f, 9.08861319e-02f, - 9.22155352e-02f, 9.35340039e-02f, 9.48414551e-02f, 9.61377996e-02f, 9.74227510e-02f, 9.86963094e-02f, - 9.99583015e-02f, 1.01208594e-01f, 1.02447040e-01f, 1.03673605e-01f, 1.04888037e-01f, 1.06090248e-01f, - 1.07280184e-01f, 1.08457678e-01f, 1.09622551e-01f, 1.10774817e-01f, 1.11914246e-01f, 1.13040752e-01f, - 1.14154230e-01f, 1.15254586e-01f, 1.16341662e-01f, 1.17415372e-01f, 1.18475656e-01f, 1.19522311e-01f, - 1.20555296e-01f, 1.21574487e-01f, 1.22579800e-01f, 1.23571123e-01f, 1.24548327e-01f, 1.25511352e-01f, - 1.26460115e-01f, 1.27394486e-01f, 1.28314377e-01f, 1.29219699e-01f, 1.30110420e-01f, 1.30986334e-01f, - 1.31847444e-01f, 1.32693620e-01f, 1.33524846e-01f, 1.34340966e-01f, 1.35141949e-01f, 1.35927700e-01f, - 1.36698083e-01f, 1.37453137e-01f, 1.38192719e-01f, 1.38916768e-01f, 1.39625212e-01f, 1.40317980e-01f, - 1.40995021e-01f, 1.41656283e-01f, 1.42301678e-01f, 1.42931088e-01f, 1.43544631e-01f, 1.44142014e-01f, - 1.44723447e-01f, 1.45288560e-01f, 1.45837628e-01f, 1.46370354e-01f, 1.46886832e-01f, 1.47386918e-01f, - 1.47870608e-01f, 1.48337891e-01f, 1.48788696e-01f, 1.49222992e-01f, 1.49640674e-01f, 1.50041862e-01f, - 1.50426360e-01f, 1.50794239e-01f, 1.51145406e-01f, 1.51479891e-01f, 1.51797638e-01f, 1.52098522e-01f, - 1.52382717e-01f, 1.52650095e-01f, 1.52900640e-01f, 1.53134329e-01f, 1.53351095e-01f, 1.53551062e-01f, - 1.53734036e-01f, 1.53900224e-01f, 1.54049447e-01f, 1.54181761e-01f, 1.54297202e-01f, 1.54395663e-01f, - 1.54477189e-01f, 1.54541822e-01f, 1.54589538e-01f, 1.54620365e-01f, 1.54634218e-01f, 1.54631148e-01f, - 1.54611295e-01f, 1.54574461e-01f, 1.54520794e-01f, 1.54450269e-01f, 1.54362965e-01f, 1.54258748e-01f, - 1.54137821e-01f, 1.54000072e-01f, 1.53845598e-01f, 1.53674440e-01f, 1.53486491e-01f, 1.53281962e-01f, - 1.53060753e-01f, 1.52822983e-01f, 1.52568622e-01f, 1.52297733e-01f, 1.52010381e-01f, 1.51706593e-01f, - 1.51386401e-01f, 1.51049821e-01f, 1.50696969e-01f, 1.50327794e-01f, 1.49942402e-01f, 1.49540911e-01f, - 1.49123245e-01f, 1.48689614e-01f, 1.48239921e-01f, 1.47774270e-01f, 1.47292757e-01f, 1.46795378e-01f, - 1.46282304e-01f, 1.45753551e-01f, 1.45209154e-01f, 1.44649160e-01f, 1.44073714e-01f, 1.43482851e-01f, - 1.42876633e-01f, 1.42255159e-01f, 1.41618448e-01f, 1.40966749e-01f, 1.40299875e-01f, 1.39618156e-01f, - 1.38921490e-01f, 1.38210089e-01f, 1.37484001e-01f, 1.36743259e-01f, 1.35988037e-01f, 1.35218348e-01f, - 1.34434364e-01f, 1.33636100e-01f, 1.32823698e-01f, 1.31997318e-01f, 1.31156846e-01f, 1.30302598e-01f, - 1.29434648e-01f, 1.28552951e-01f, 1.27657774e-01f, 1.26749209e-01f, 1.25827205e-01f, 1.24892057e-01f, - 1.23943743e-01f, 1.22982472e-01f, 1.22008301e-01f, 1.21021365e-01f, 1.20021759e-01f, 1.19009627e-01f, - 1.17985061e-01f, 1.16948192e-01f, 1.15899120e-01f, 1.14837992e-01f, 1.13764978e-01f, 1.12680080e-01f, - 1.11583571e-01f, 1.10475411e-01f, 1.09355916e-01f, 1.08225061e-01f, 1.07083052e-01f, 1.05929966e-01f, - 1.04766014e-01f, 1.03591285e-01f, 1.02405887e-01f, 1.01210043e-01f, 1.00003801e-01f, 9.87873356e-02f, - 9.75607704e-02f, 9.63243150e-02f, 9.50779930e-02f, 9.38220243e-02f, 9.25565366e-02f, 9.12816837e-02f, - 8.99975874e-02f, 8.87044403e-02f, 8.74023768e-02f, 8.60914543e-02f, 8.47719457e-02f, 8.34439520e-02f, - 8.21075970e-02f, 8.07630565e-02f, 7.94105358e-02f, 7.80500907e-02f, 7.66819641e-02f, 7.53062356e-02f, - 7.39230872e-02f, 7.25326644e-02f, 7.11351731e-02f, 6.97307905e-02f, 6.83195285e-02f, 6.69016831e-02f, - 6.54774291e-02f, 6.40468073e-02f, 6.26100565e-02f, 6.11673221e-02f, 5.97187977e-02f, 5.82646242e-02f, - 5.68049135e-02f, 5.53399769e-02f, 5.38697412e-02f, 5.23946080e-02f, 5.09145732e-02f, 4.94299600e-02f, - 4.79407638e-02f, 4.64473174e-02f, 4.49496311e-02f, 4.34479780e-02f, 4.19425210e-02f, 4.04333799e-02f, - 3.89208156e-02f, 3.74048242e-02f, 3.58856995e-02f, 3.43636119e-02f, 3.28387395e-02f, 3.13112247e-02f, - 2.97811889e-02f, 2.82488742e-02f, 2.67144183e-02f, 2.51780473e-02f, 2.36398335e-02f, 2.21000042e-02f, - 2.05587399e-02f, 1.90162375e-02f, 1.74725727e-02f, 1.59280289e-02f, 1.43826692e-02f, 1.28367555e-02f, - 1.12904149e-02f, 9.74379635e-03f, 8.19714000e-03f, 6.65052578e-03f, 5.10426344e-03f, 3.55837408e-03f, - 2.01311138e-03f, 4.68618885e-04f, -1.07492802e-03f, -2.61734002e-03f, -4.15846945e-03f, -5.69811418e-03f, - -7.23618261e-03f, -8.77239400e-03f, -1.03067045e-02f, -1.18388198e-02f, -1.33686294e-02f, -1.48960149e-02f, - -1.64206972e-02f, -1.79425842e-02f, -1.94615116e-02f, -2.09772728e-02f, -2.24897492e-02f, -2.39987326e-02f, - -2.55040912e-02f, -2.70056181e-02f, -2.85032033e-02f, -2.99966384e-02f, -3.14857235e-02f, -3.29704263e-02f, - -3.44504746e-02f, -3.59257643e-02f, -3.73960799e-02f, -3.88613043e-02f, -4.03212167e-02f, -4.17757533e-02f, - -4.32246557e-02f, -4.46678714e-02f, -4.61051227e-02f, -4.75363676e-02f, -4.89613920e-02f, -5.03800130e-02f, - -5.17921608e-02f, -5.31976091e-02f, -5.45962455e-02f, -5.59878778e-02f, -5.73724080e-02f, -5.87495943e-02f, - -6.01194398e-02f, -6.14816736e-02f, -6.28361792e-02f, -6.41827950e-02f, -6.55214065e-02f, -6.68518684e-02f, - -6.81740121e-02f, -6.94877209e-02f, -7.07928273e-02f, -7.20891935e-02f, -7.33767244e-02f, -7.46552221e-02f, - -7.59246023e-02f, -7.71846358e-02f, -7.84353153e-02f, -7.96764866e-02f, -8.09078338e-02f, -8.21294906e-02f, - -8.33411198e-02f, -8.45427469e-02f, -8.57341047e-02f, -8.69151828e-02f, -8.80857322e-02f, -8.92457674e-02f, - -9.03950885e-02f, -9.15335446e-02f, -9.26611125e-02f, -9.37775503e-02f, -9.48828588e-02f, -9.59767695e-02f, - -9.70593544e-02f, -9.81303392e-02f, -9.91897208e-02f, -1.00237304e-01f, -1.01273063e-01f, -1.02296805e-01f, - -1.03308488e-01f, -1.04307943e-01f, -1.05295136e-01f, -1.06269917e-01f, -1.07232171e-01f, -1.08181856e-01f, - -1.09118832e-01f, -1.10042992e-01f, -1.10954185e-01f, -1.11852491e-01f, -1.12737699e-01f, -1.13609672e-01f, - -1.14468420e-01f, -1.15313765e-01f, -1.16145740e-01f, -1.16964157e-01f, -1.17768925e-01f, -1.18560046e-01f, - -1.19337356e-01f, -1.20100822e-01f, -1.20850331e-01f, -1.21585866e-01f, -1.22307291e-01f, -1.23014547e-01f, - -1.23707640e-01f, -1.24386317e-01f, -1.25050725e-01f, -1.25700671e-01f, -1.26336067e-01f, -1.26956987e-01f, - -1.27563207e-01f, -1.28154789e-01f, -1.28731607e-01f, -1.29293650e-01f, -1.29840790e-01f, -1.30373095e-01f, - -1.30890385e-01f, -1.31392667e-01f, -1.31879918e-01f, -1.32352055e-01f, -1.32809036e-01f, -1.33250832e-01f, - -1.33677357e-01f, -1.34088721e-01f, -1.34484639e-01f, -1.34865292e-01f, -1.35230535e-01f, -1.35580371e-01f, - -1.35914785e-01f, -1.36233743e-01f, -1.36537078e-01f, -1.36825039e-01f, -1.37097320e-01f, -1.37354175e-01f, - -1.37595260e-01f, -1.37820881e-01f, -1.38030815e-01f, -1.38225099e-01f, -1.38403751e-01f, -1.38566654e-01f, - -1.38714017e-01f, -1.38845537e-01f, -1.38961525e-01f, -1.39061705e-01f, -1.39146208e-01f, -1.39215007e-01f, - -1.39268083e-01f, -1.39305540e-01f, -1.39327211e-01f, -1.39333281e-01f, -1.39323617e-01f, -1.39298265e-01f, - -1.39257268e-01f, -1.39200631e-01f, -1.39128385e-01f, -1.39040488e-01f, -1.38937007e-01f, -1.38817919e-01f, - -1.38683315e-01f, -1.38533210e-01f, -1.38367540e-01f, -1.38186391e-01f, -1.37989790e-01f, -1.37777779e-01f, - -1.37550424e-01f, -1.37307600e-01f, -1.37049521e-01f, -1.36776169e-01f, -1.36487614e-01f, -1.36183772e-01f, - -1.35864811e-01f, -1.35530712e-01f, -1.35181560e-01f, -1.34817367e-01f, -1.34438209e-01f, -1.34044133e-01f, - -1.33635169e-01f, -1.33211403e-01f, -1.32772844e-01f, -1.32319595e-01f, -1.31851753e-01f, -1.31369242e-01f, - -1.30872280e-01f, -1.30360792e-01f, -1.29834936e-01f, -1.29294720e-01f, -1.28740281e-01f, -1.28171682e-01f, - -1.27588895e-01f, -1.26992136e-01f, -1.26381341e-01f, -1.25756680e-01f, -1.25118173e-01f, -1.24466017e-01f, - -1.23800103e-01f, -1.23120667e-01f, -1.22427722e-01f, -1.21721393e-01f, -1.21001688e-01f, -1.20268848e-01f, - -1.19522781e-01f, -1.18763721e-01f, -1.17991703e-01f, -1.17206801e-01f, -1.16409124e-01f, -1.15598804e-01f, - -1.14775879e-01f, -1.13940474e-01f, -1.13092744e-01f, -1.12232702e-01f, -1.11360508e-01f, -1.10476277e-01f, - -1.09580068e-01f, -1.08672013e-01f, -1.07752234e-01f, -1.06820817e-01f, -1.05877861e-01f, -1.04923522e-01f, - -1.03957909e-01f, -1.02981089e-01f, -1.01993228e-01f, -1.00994384e-01f, -9.99847668e-02f, -9.89644233e-02f, - -9.79335196e-02f, -9.68921559e-02f, -9.58404130e-02f, -9.47785234e-02f, -9.37064783e-02f, -9.26244846e-02f, - -9.15326815e-02f, -9.04311612e-02f, -8.93200949e-02f, -8.81995284e-02f, -8.70697004e-02f, -8.59306705e-02f, - -8.47825862e-02f, -8.36256039e-02f, -8.24598514e-02f, -8.12854373e-02f, -8.01025303e-02f, -7.89113227e-02f, - -7.77117944e-02f, -7.65042084e-02f, -7.52886880e-02f, -7.40653936e-02f, -7.28344148e-02f, -7.15959136e-02f, - -7.03500302e-02f, -6.90969649e-02f, -6.78368523e-02f, -6.65696438e-02f, -6.52958215e-02f, -6.40152341e-02f, - -6.27282711e-02f, -6.14348937e-02f, -6.01353576e-02f, -5.88297420e-02f, -5.75182513e-02f, -5.62010584e-02f, - -5.48782313e-02f, -5.35500381e-02f, -5.22164829e-02f, -5.08778643e-02f, -4.95342471e-02f, -4.81858053e-02f, - -4.68327485e-02f, -4.54751266e-02f, -4.41132169e-02f, -4.27470791e-02f, -4.13769276e-02f, -4.00028701e-02f, - -3.86250995e-02f, -3.72438291e-02f, -3.58590799e-02f, -3.44711540e-02f, -3.30800714e-02f, -3.16861153e-02f, - -3.02893897e-02f, -2.88900305e-02f, -2.74883087e-02f, -2.60841906e-02f, -2.46780469e-02f, -2.32698916e-02f, - -2.18599651e-02f, -2.04483433e-02f, -1.90353004e-02f, -1.76209590e-02f, -1.62053882e-02f, -1.47888599e-02f, - -1.33714932e-02f, -1.19534890e-02f, -1.05349334e-02f, -9.11605164e-03f, -7.69693506e-03f, -6.27787764e-03f, - -4.85886448e-03f, -3.44024502e-03f, -2.02202613e-03f, -6.04449349e-04f, 8.12338042e-04f, 2.22825583e-03f, - 3.64297636e-03f, 5.05648242e-03f, 6.46854432e-03f, 7.87908626e-03f, 9.28781195e-03f, 1.06946732e-02f, - 1.20994599e-02f, 1.35019880e-02f, 1.49022354e-02f, 1.62998618e-02f, 1.76948771e-02f, 1.90869374e-02f, - 2.04760582e-02f, 2.18619393e-02f, 2.32446010e-02f, 2.46237157e-02f, 2.59992103e-02f, 2.73709541e-02f, - 2.87387265e-02f, 3.01023715e-02f, 3.14618406e-02f, 3.28168461e-02f, 3.41673746e-02f, 3.55131296e-02f, - 3.68540176e-02f, 3.81899212e-02f, 3.95206494e-02f, 4.08461354e-02f, 4.21661538e-02f, 4.34805300e-02f, - 4.47891609e-02f, 4.60919277e-02f, 4.73885882e-02f, 4.86791520e-02f, 4.99633486e-02f, 5.12410462e-02f, - 5.25121855e-02f, 5.37765585e-02f, 5.50339990e-02f, 5.62844059e-02f, 5.75276411e-02f, 5.87635813e-02f, - 5.99920799e-02f, 6.12129552e-02f, 6.24261119e-02f, 6.36314078e-02f, 6.48287729e-02f, 6.60179606e-02f, - 6.71988858e-02f, 6.83714411e-02f, 6.95354851e-02f, 7.06909290e-02f, 7.18374735e-02f, 7.29752248e-02f, - 7.41039142e-02f, 7.52234707e-02f, 7.63338064e-02f, 7.74345827e-02f, 7.85260436e-02f, 7.96077386e-02f, - 8.06797676e-02f, 8.17418379e-02f, 8.27940029e-02f, 8.38360715e-02f, 8.48678264e-02f, 8.58893317e-02f, - 8.69003224e-02f, 8.79008506e-02f, 8.88906863e-02f, 8.98697684e-02f, 9.08379564e-02f, 9.17951785e-02f, - 9.27413187e-02f, 9.36762171e-02f, 9.45998845e-02f, 9.55121957e-02f, 9.64129950e-02f, 9.73021895e-02f, - 9.81797129e-02f, 9.90454670e-02f, 9.98993396e-02f, 1.00741297e-01f, 1.01571187e-01f, 1.02388933e-01f, - 1.03194486e-01f, 1.03987675e-01f, 1.04768532e-01f, 1.05536853e-01f, 1.06292637e-01f, 1.07035802e-01f, - 1.07766234e-01f, 1.08483820e-01f, 1.09188660e-01f, 1.09880415e-01f, 1.10559289e-01f, 1.11224946e-01f, - 1.11877534e-01f, 1.12516830e-01f, 1.13142924e-01f, 1.13755567e-01f, 1.14354840e-01f, 1.14940612e-01f, - 1.15512802e-01f, 1.16071479e-01f, 1.16616434e-01f, 1.17147731e-01f, 1.17665157e-01f, 1.18168848e-01f, - 1.18658622e-01f, 1.19134504e-01f, 1.19596442e-01f, 1.20044301e-01f, 1.20478154e-01f, 1.20897880e-01f, - 1.21303477e-01f, 1.21694873e-01f, 1.22072043e-01f, 1.22434995e-01f, 1.22783641e-01f, 1.23117969e-01f, - 1.23437934e-01f, 1.23743497e-01f, 1.24034656e-01f, 1.24311419e-01f, 1.24573690e-01f, 1.24821505e-01f, - 1.25054748e-01f, 1.25273525e-01f, 1.25477770e-01f, 1.25667417e-01f, 1.25842489e-01f, 1.26003003e-01f, - 1.26148882e-01f, 1.26280181e-01f, 1.26396850e-01f, 1.26498979e-01f, 1.26586382e-01f, 1.26659198e-01f, - 1.26717382e-01f, 1.26760958e-01f, 1.26789912e-01f, 1.26804172e-01f, 1.26803885e-01f, 1.26789023e-01f, - 1.26759486e-01f, 1.26715356e-01f, 1.26656759e-01f, 1.26583474e-01f, 1.26495753e-01f, 1.26393393e-01f, - 1.26276651e-01f, 1.26145299e-01f, 1.25999578e-01f, 1.25839347e-01f, 1.25664728e-01f, 1.25475738e-01f, - 1.25272360e-01f, 1.25054700e-01f, 1.24822663e-01f, 1.24576471e-01f, 1.24315954e-01f, 1.24041298e-01f, - 1.23752444e-01f, 1.23449545e-01f, 1.23132547e-01f, 1.22801548e-01f, 1.22456555e-01f, 1.22097593e-01f, - 1.21724827e-01f, 1.21338117e-01f, 1.20937688e-01f, 1.20523534e-01f, 1.20095734e-01f, 1.19654263e-01f, - 1.19199239e-01f, 1.18730703e-01f, 1.18248754e-01f, 1.17753450e-01f, 1.17244798e-01f, 1.16722898e-01f, - 1.16187812e-01f, 1.15639642e-01f, 1.15078393e-01f, 1.14504142e-01f, 1.13917031e-01f, 1.13317136e-01f, - 1.12704424e-01f, 1.12079078e-01f, 1.11441104e-01f, 1.10790641e-01f, 1.10127737e-01f, 1.09452491e-01f, - 1.08764962e-01f, 1.08065275e-01f, 1.07353501e-01f, 1.06629661e-01f, 1.05893965e-01f, 1.05146394e-01f, - 1.04387153e-01f, 1.03616229e-01f, 1.02833826e-01f, 1.02039819e-01f, 1.01234625e-01f, 1.00418092e-01f, - 9.95904542e-02f, 9.87517247e-02f, 9.79020560e-02f, 9.70416000e-02f, 9.61703225e-02f, 9.52884289e-02f, - 9.43960389e-02f, 9.34931938e-02f, 9.25801114e-02f, 9.16567883e-02f, 9.07233492e-02f, 8.97799309e-02f, - 8.88267198e-02f, 8.78636973e-02f, 8.68910829e-02f, 8.59089739e-02f, 8.49174462e-02f, 8.39166393e-02f, - 8.29066935e-02f, 8.18877107e-02f, 8.08598615e-02f, 7.98231786e-02f, 7.87778506e-02f, 7.77239836e-02f, - 7.66616737e-02f, 7.55911049e-02f, 7.45124153e-02f, 7.34256906e-02f, 7.23310393e-02f, 7.12286795e-02f, - 7.01185962e-02f, 6.90010794e-02f, 6.78761816e-02f, 6.67440040e-02f, 6.56048215e-02f, 6.44586303e-02f, - 6.33055870e-02f, 6.21458887e-02f, 6.09795825e-02f, 5.98069460e-02f, 5.86279373e-02f, 5.74429047e-02f, - 5.62517911e-02f, 5.50548519e-02f, 5.38522003e-02f, 5.26439664e-02f, 5.14303081e-02f, 5.02113696e-02f, - 4.89872739e-02f, 4.77582093e-02f, 4.65242865e-02f, 4.52856462e-02f, 4.40424824e-02f, 4.27948610e-02f, - 4.15429862e-02f, 4.02869717e-02f, 3.90270246e-02f, 3.77632228e-02f, 3.64958050e-02f, 3.52247833e-02f, - 3.39504262e-02f, 3.26728565e-02f, 3.13921910e-02f, 3.01085942e-02f, 2.88221717e-02f, 2.75332201e-02f, - 2.62417232e-02f, 2.49479709e-02f, 2.36519783e-02f, 2.23539460e-02f, 2.10540973e-02f, 1.97524930e-02f, - 1.84494507e-02f, 1.71448229e-02f, 1.58390175e-02f, 1.45320776e-02f, 1.32241728e-02f, 1.19154782e-02f, - 1.06061469e-02f, 9.29629339e-03f, 7.98613717e-03f, 6.67571191e-03f, 5.36528989e-03f, 4.05497439e-03f, - 2.74491221e-03f, 1.43525629e-03f, 1.26200446e-04f, -1.18219175e-03f, -2.48966420e-03f, -3.79613924e-03f, - -5.10143701e-03f, -6.40542130e-03f, -7.70795763e-03f, -9.00878808e-03f, -1.03078615e-02f, -1.16050830e-02f, - -1.29001768e-02f, -1.41930830e-02f, -1.54835549e-02f, -1.67715314e-02f, -1.80568413e-02f, -1.93393502e-02f, - -2.06188098e-02f, -2.18952560e-02f, -2.31683787e-02f, -2.44381508e-02f, -2.57042848e-02f, -2.69667704e-02f, - -2.82253811e-02f, -2.94800527e-02f, -3.07305679e-02f, -3.19767381e-02f, -3.32185872e-02f, -3.44558387e-02f, - -3.56883978e-02f, -3.69160578e-02f, -3.81387642e-02f, -3.93563332e-02f, -4.05686591e-02f, -4.17755783e-02f, - -4.29769263e-02f, -4.41726467e-02f, -4.53625024e-02f, -4.65464470e-02f, -4.77242333e-02f, -4.88958535e-02f, - -5.00611033e-02f, -5.12198862e-02f, -5.23720315e-02f, -5.35174255e-02f, -5.46559770e-02f, -5.57874860e-02f, - -5.69118272e-02f, -5.80289472e-02f, -5.91386613e-02f, -6.02409018e-02f, -6.13354020e-02f, -6.24221660e-02f, - -6.35010731e-02f, -6.45719662e-02f, -6.56347616e-02f, -6.66892214e-02f, -6.77353623e-02f, -6.87729739e-02f, - -6.98020221e-02f, -7.08223670e-02f, -7.18338252e-02f, -7.28363159e-02f, -7.38297795e-02f, -7.48140733e-02f, - -7.57890338e-02f, -7.67546907e-02f, -7.77107588e-02f, -7.86573033e-02f, -7.95940027e-02f, -8.05210027e-02f, - -8.14380357e-02f, -8.23450529e-02f, -8.32419190e-02f, -8.41285836e-02f, -8.50048978e-02f, -8.58708211e-02f, - -8.67262039e-02f, -8.75709405e-02f, -8.84050521e-02f, -8.92283333e-02f, -9.00407176e-02f, -9.08420951e-02f, - -9.16324107e-02f, -9.24116308e-02f, -9.31795457e-02f, -9.39361905e-02f, -9.46813663e-02f, -9.54151226e-02f, - -9.61372471e-02f, -9.68477375e-02f, -9.75465337e-02f, -9.82335129e-02f, -9.89085667e-02f, -9.95717152e-02f, - -1.00222908e-01f, -1.00861947e-01f, -1.01488805e-01f, -1.02103473e-01f, -1.02705794e-01f, -1.03295854e-01f, - -1.03873381e-01f, -1.04438527e-01f, -1.04991043e-01f, -1.05531018e-01f, -1.06058323e-01f, -1.06572910e-01f, - -1.07074721e-01f, -1.07563692e-01f, -1.08039865e-01f, -1.08503035e-01f, -1.08953283e-01f, -1.09390521e-01f, - -1.09814694e-01f, -1.10225765e-01f, -1.10623675e-01f, -1.11008366e-01f, -1.11379892e-01f, -1.11738136e-01f, - -1.12083110e-01f, -1.12414720e-01f, -1.12732955e-01f, -1.13037848e-01f, -1.13329286e-01f, -1.13607296e-01f, - -1.13871793e-01f, -1.14122796e-01f, -1.14360310e-01f, -1.14584225e-01f, -1.14794660e-01f, -1.14991407e-01f, - -1.15174644e-01f, -1.15344183e-01f, -1.15500174e-01f, -1.15642513e-01f, -1.15771161e-01f, -1.15886209e-01f, - -1.15987501e-01f, -1.16075237e-01f, -1.16149182e-01f, -1.16209543e-01f, -1.16256188e-01f, -1.16289167e-01f, - -1.16308483e-01f, -1.16314104e-01f, -1.16306085e-01f, -1.16284404e-01f, -1.16249103e-01f, -1.16200168e-01f, - -1.16137522e-01f, -1.16061366e-01f, -1.15971571e-01f, -1.15868223e-01f, -1.15751288e-01f, -1.15620848e-01f, - -1.15476905e-01f, -1.15319457e-01f, -1.15148508e-01f, -1.14964110e-01f, -1.14766351e-01f, -1.14555176e-01f, - -1.14330694e-01f, -1.14092845e-01f, -1.13841755e-01f, -1.13577426e-01f, -1.13299812e-01f, -1.13009068e-01f, - -1.12705154e-01f, -1.12388213e-01f, -1.12058233e-01f, -1.11715189e-01f, -1.11359227e-01f, -1.10990363e-01f, - -1.10608615e-01f, -1.10214084e-01f, -1.09806767e-01f, -1.09386849e-01f, -1.08954199e-01f, -1.08508984e-01f, - -1.08051204e-01f, -1.07580993e-01f, -1.07098371e-01f, -1.06603415e-01f, -1.06096165e-01f, -1.05576685e-01f, - -1.05045080e-01f, -1.04501397e-01f, -1.03945692e-01f, -1.03378039e-01f, -1.02798540e-01f, -1.02207211e-01f, - -1.01604242e-01f, -1.00989539e-01f, -1.00363358e-01f, -9.97256086e-02f, -9.90765022e-02f, -9.84160764e-02f, - -9.77444313e-02f, -9.70615861e-02f, -9.63676691e-02f, -9.56628018e-02f, -9.49470420e-02f, -9.42205139e-02f, - -9.34831825e-02f, -9.27352752e-02f, -9.19768591e-02f, -9.12079498e-02f, -9.04287421e-02f, -8.96393173e-02f, - -8.88397171e-02f, -8.80300957e-02f, -8.72104869e-02f, -8.63810837e-02f, -8.55418788e-02f, -8.46931130e-02f, - -8.38347386e-02f, -8.29669978e-02f, -8.20898871e-02f, -8.12035912e-02f, -8.03081794e-02f, -7.94037839e-02f, - -7.84905137e-02f, -7.75684527e-02f, -7.66377464e-02f, -7.56984918e-02f, -7.47507966e-02f, -7.37947508e-02f, - -7.28305633e-02f, -7.18582769e-02f, -7.08780756e-02f, -6.98899285e-02f, -6.88941705e-02f, -6.78907286e-02f, - -6.68798706e-02f, -6.58615854e-02f, -6.48361189e-02f, -6.38035208e-02f, -6.27639302e-02f, -6.17175137e-02f, - -6.06643579e-02f, -5.96045927e-02f, -5.85383079e-02f, -5.74657549e-02f, -5.63869590e-02f, -5.53020502e-02f, - -5.42111913e-02f, -5.31145205e-02f, -5.20121622e-02f, -5.09042491e-02f, -4.97908914e-02f, -4.86722294e-02f, - -4.75484140e-02f, -4.64196077e-02f, -4.52859083e-02f, -4.41474167e-02f, -4.30043767e-02f, -4.18567690e-02f, - -4.07049111e-02f, -3.95487853e-02f, -3.83886644e-02f, -3.72245553e-02f, -3.60567029e-02f, -3.48851842e-02f, - -3.37101768e-02f, -3.25317712e-02f, -3.13501720e-02f, -3.01655183e-02f, -2.89778725e-02f, -2.77874347e-02f, - -2.65943493e-02f, -2.53987630e-02f, -2.42007827e-02f, -2.30005668e-02f, -2.17982718e-02f, -2.05940314e-02f, - -1.93880144e-02f, -1.81803166e-02f, -1.69711233e-02f, -1.57605243e-02f, -1.45487328e-02f, -1.33358554e-02f, - -1.21220093e-02f, -1.09074318e-02f, -9.69208142e-03f, -8.47632726e-03f, -7.26019934e-03f, -6.04383636e-03f, - -4.82739438e-03f, -3.61104652e-03f, -2.39488672e-03f, -1.17907356e-03f, 3.62207932e-05f, 1.25084075e-03f, - 2.46473019e-03f, 3.67765816e-03f, 4.88955407e-03f, 6.10018668e-03f, 7.30946050e-03f, 8.51728194e-03f, - 9.72337551e-03f, 1.09277610e-02f, 1.21301810e-02f, 1.33305425e-02f, 1.45286892e-02f, 1.57244906e-02f, - 1.69178019e-02f, 1.81084783e-02f, 1.92963650e-02f, 2.04813523e-02f, 2.16633536e-02f, 2.28420998e-02f, - 2.40175365e-02f, 2.51894871e-02f, 2.63578211e-02f, 2.75224962e-02f, 2.86832624e-02f, 2.98399937e-02f, - 3.09925964e-02f, 3.21409113e-02f, 3.32847943e-02f, 3.44242004e-02f, 3.55588637e-02f, 3.66888020e-02f, - 3.78136808e-02f, 3.89335197e-02f, 4.00481913e-02f, 4.11575169e-02f, 4.22613601e-02f, 4.33596435e-02f, - 4.44521638e-02f, 4.55388571e-02f, 4.66195887e-02f, 4.76942119e-02f, 4.87626104e-02f, 4.98246687e-02f, - 5.08802490e-02f, 5.19292769e-02f, 5.29715536e-02f, 5.40070243e-02f, 5.50355139e-02f, 5.60569512e-02f, - 5.70711651e-02f, 5.80781156e-02f, 5.90776427e-02f, 6.00695883e-02f, 6.10539458e-02f, 6.20304648e-02f, - 6.29992141e-02f, 6.39598706e-02f, 6.49124430e-02f, 6.58568623e-02f, 6.67929701e-02f, 6.77205841e-02f, - 6.86397006e-02f, 6.95502000e-02f, 7.04519300e-02f, 7.13448621e-02f, 7.22287988e-02f, 7.31037649e-02f, - 7.39694950e-02f, 7.48260868e-02f, 7.56731969e-02f, 7.65110110e-02f, 7.73392685e-02f, 7.81578195e-02f, - 7.89667583e-02f, 7.97657643e-02f, 8.05549813e-02f, 8.13341571e-02f, 8.21032741e-02f, 8.28622239e-02f, - 8.36109147e-02f, 8.43493189e-02f, 8.50772588e-02f, 8.57946849e-02f, 8.65015882e-02f, 8.71977517e-02f, - 8.78832912e-02f, 8.85579298e-02f, 8.92217449e-02f, 8.98745453e-02f, 9.05163369e-02f, 9.11470571e-02f, - 9.17665657e-02f, 9.23748370e-02f, 9.29717807e-02f, 9.35573894e-02f, 9.41315283e-02f, 9.46941724e-02f, - 9.52452372e-02f, 9.57846876e-02f, 9.63125098e-02f, 9.68285429e-02f, 9.73327589e-02f, 9.78251629e-02f, - 9.83056363e-02f, 9.87741980e-02f, 9.92306662e-02f, 9.96751491e-02f, 1.00107514e-01f, 1.00527742e-01f, - 1.00935788e-01f, 1.01331533e-01f, 1.01715100e-01f, 1.02086281e-01f, 1.02445133e-01f, 1.02791579e-01f, - 1.03125622e-01f, 1.03447155e-01f, 1.03756250e-01f, 1.04052773e-01f, 1.04336778e-01f, 1.04608206e-01f, - 1.04866974e-01f, 1.05113158e-01f, 1.05346673e-01f, 1.05567517e-01f, 1.05775631e-01f, 1.05971027e-01f, - 1.06153727e-01f, 1.06323634e-01f, 1.06480807e-01f, 1.06625172e-01f, 1.06756767e-01f, 1.06875574e-01f, - 1.06981499e-01f, 1.07074702e-01f, 1.07155065e-01f, 1.07222553e-01f, 1.07277262e-01f, 1.07319131e-01f, - 1.07348189e-01f, 1.07364428e-01f, 1.07367749e-01f, 1.07358390e-01f, 1.07336150e-01f, 1.07301131e-01f, - 1.07253303e-01f, 1.07192760e-01f, 1.07119400e-01f, 1.07033292e-01f, 1.06934469e-01f, 1.06822920e-01f, - 1.06698674e-01f, 1.06561773e-01f, 1.06412200e-01f, 1.06250029e-01f, 1.06075184e-01f, 1.05887818e-01f, - 1.05687863e-01f, 1.05475457e-01f, 1.05250524e-01f, 1.05013071e-01f, 1.04763312e-01f, 1.04501066e-01f, - 1.04226554e-01f, 1.03939672e-01f, 1.03640561e-01f, 1.03329191e-01f, 1.03005619e-01f, 1.02669951e-01f, - 1.02322083e-01f, 1.01962285e-01f, 1.01590453e-01f, 1.01206638e-01f, 1.00810972e-01f, 1.00403408e-01f, - 9.99840819e-02f, 9.95529986e-02f, 9.91102343e-02f, 9.86558727e-02f, 9.81898809e-02f, 9.77124823e-02f, - 9.72235728e-02f, 9.67233288e-02f, 9.62117435e-02f, 9.56889064e-02f, 9.51549330e-02f, 9.46097951e-02f, - 9.40536953e-02f, 9.34865683e-02f, 9.29085427e-02f, 9.23197157e-02f, 9.17201330e-02f, 9.11098914e-02f, - 9.04890775e-02f, 8.98577234e-02f, 8.92159421e-02f, 8.85638465e-02f, 8.79014626e-02f, 8.72288677e-02f, - 8.65462319e-02f, 8.58534940e-02f, 8.51508625e-02f, 8.44384589e-02f, 8.37162860e-02f, 8.29844203e-02f, - 8.22430044e-02f, 8.14921064e-02f, 8.07319044e-02f, 7.99623265e-02f, 7.91836304e-02f, 7.83957645e-02f, - 7.75989951e-02f, 7.67933370e-02f, 7.59788409e-02f, 7.51556819e-02f, 7.43238977e-02f, 7.34836653e-02f, - 7.26350525e-02f, 7.17781961e-02f, 7.09131573e-02f, 7.00400357e-02f, 6.91589750e-02f, 6.82700696e-02f, - 6.73734563e-02f, 6.64692003e-02f, 6.55574424e-02f, 6.46382555e-02f, 6.37118280e-02f, 6.27782397e-02f, - 6.18375704e-02f, 6.08899910e-02f, 5.99355481e-02f, 5.89744213e-02f, 5.80067094e-02f, 5.70325558e-02f, - 5.60520157e-02f, 5.50652765e-02f, 5.40724053e-02f, 5.30735643e-02f, 5.20689185e-02f, 5.10584252e-02f, - 5.00424289e-02f, 4.90207727e-02f, 4.79939327e-02f, 4.69617698e-02f, 4.59245400e-02f, 4.48822642e-02f, - 4.38351403e-02f, 4.27832936e-02f, 4.17268700e-02f, 4.06659324e-02f, 3.96006521e-02f, 3.85311781e-02f, - 3.74575993e-02f, 3.63800577e-02f, 3.52987054e-02f, 3.42136394e-02f, 3.31250288e-02f, 3.20330065e-02f, - 3.09376260e-02f, 2.98391553e-02f, 2.87376085e-02f, 2.76331496e-02f, 2.65259938e-02f, 2.54161523e-02f, - 2.43038309e-02f, 2.31891352e-02f, 2.20722311e-02f, 2.09532056e-02f, 1.98322457e-02f, 1.87094776e-02f, - 1.75849736e-02f, 1.64589884e-02f, 1.53315375e-02f, 1.42028302e-02f, 1.30730078e-02f, 1.19421258e-02f, - 1.08104180e-02f, 9.67792952e-03f, 8.54487467e-03f, 7.41136317e-03f, 6.27750420e-03f, 5.14350993e-03f, - 4.00939231e-03f, 2.87541118e-03f, 1.74159345e-03f, 6.08190067e-04f, -5.24705239e-04f, -1.65708250e-03f, - -2.78859168e-03f, -3.91926024e-03f, -5.04885911e-03f, -6.17729285e-03f, -7.30442180e-03f, -8.43007695e-03f, - -9.55423876e-03f, -1.06766349e-02f, -1.17972269e-02f, -1.29158256e-02f, -1.40322878e-02f, -1.51465740e-02f, - -1.62584255e-02f, -1.73677945e-02f, -1.84744767e-02f, -1.95784452e-02f, -2.06794673e-02f, -2.17774786e-02f, - -2.28723172e-02f, -2.39639100e-02f, -2.50520071e-02f, -2.61366005e-02f, -2.72174729e-02f, -2.82945395e-02f, - -2.93676905e-02f, -3.04367168e-02f, -3.15016003e-02f, -3.25621596e-02f, -3.36183156e-02f, -3.46698325e-02f, - -3.57166998e-02f, -3.67587216e-02f, -3.77958035e-02f, -3.88278095e-02f, -3.98546612e-02f, -4.08762250e-02f, - -4.18923211e-02f, -4.29028944e-02f, -4.39077555e-02f, -4.49068739e-02f, -4.59000594e-02f, -4.68872743e-02f, - -4.78683064e-02f, -4.88431223e-02f, -4.98115812e-02f, -5.07735204e-02f, -5.17289069e-02f, -5.26775596e-02f, - -5.36194415e-02f, -5.45543409e-02f, -5.54822573e-02f, -5.64029734e-02f, -5.73164811e-02f, -5.82225831e-02f, - -5.91213583e-02f, -6.00123906e-02f, -6.08958803e-02f, -6.17715347e-02f, -6.26393413e-02f, -6.34991469e-02f, - -6.43508914e-02f, -6.51944683e-02f, -6.60297058e-02f, -6.68566222e-02f, -6.76750639e-02f, -6.84849756e-02f, - -6.92861907e-02f, -7.00786771e-02f, -7.08623560e-02f, -7.16370528e-02f, -7.24027343e-02f, -7.31593128e-02f, - -7.39066855e-02f, -7.46448248e-02f, -7.53735676e-02f, -7.60928636e-02f, -7.68026362e-02f, -7.75027344e-02f, - -7.81932482e-02f, -7.88738969e-02f, -7.95447356e-02f, -8.02056781e-02f, -8.08565312e-02f, -8.14974603e-02f, - -8.21280575e-02f, -8.27485990e-02f, -8.33586842e-02f, -8.39585813e-02f, -8.45479461e-02f, -8.51268389e-02f, - -8.56951652e-02f, -8.62528717e-02f, -8.67999538e-02f, -8.73361794e-02f, -8.78617012e-02f, -8.83763207e-02f, - -8.88800233e-02f, -8.93727698e-02f, -8.98543884e-02f, -9.03250183e-02f, -9.07844890e-02f, -9.12328168e-02f, - -9.16698343e-02f, -9.20955516e-02f, -9.25099980e-02f, -9.29130616e-02f, -9.33047136e-02f, -9.36848408e-02f, - -9.40535640e-02f, -9.44106207e-02f, -9.47562233e-02f, -9.50901587e-02f, -9.54124516e-02f, -9.57230281e-02f, - -9.60219352e-02f, -9.63090338e-02f, -9.65844316e-02f, -9.68479630e-02f, -9.70996953e-02f, -9.73395356e-02f, - -9.75675070e-02f, -9.77836139e-02f, -9.79877546e-02f, -9.81799567e-02f, -9.83602382e-02f, -9.85285008e-02f, - -9.86847703e-02f, -9.88290574e-02f, -9.89613132e-02f, -9.90815138e-02f, -9.91897642e-02f, -9.92858206e-02f, - -9.93699798e-02f, -9.94419700e-02f, -9.95019963e-02f, -9.95498497e-02f, -9.95857386e-02f, -9.96095172e-02f, - -9.96212711e-02f, -9.96209020e-02f, -9.96085219e-02f, -9.95841309e-02f, -9.95476609e-02f, -9.94991809e-02f, - -9.94386887e-02f, -9.93662161e-02f, -9.92817066e-02f, -9.91852652e-02f, -9.90768631e-02f, -9.89565307e-02f, - -9.88242338e-02f, -9.86801252e-02f, -9.85240704e-02f, -9.83562058e-02f, -9.81764901e-02f, -9.79850061e-02f, - -9.77817490e-02f, -9.75667346e-02f, -9.73400394e-02f, -9.71016603e-02f, -9.68516404e-02f, -9.65899664e-02f, - -9.63168065e-02f, -9.60321125e-02f, -9.57358838e-02f, -9.54282375e-02f, -9.51091587e-02f, -9.47787028e-02f, - -9.44369647e-02f, -9.40839712e-02f, -9.37197083e-02f, -9.33442748e-02f, -9.29577592e-02f, -9.25601088e-02f, - -9.21514461e-02f, -9.17318870e-02f, -9.13013373e-02f, -9.08600121e-02f, -9.04078141e-02f, -8.99449574e-02f, - -8.94713102e-02f, -8.89871734e-02f, -8.84924259e-02f, -8.79872106e-02f, -8.74715780e-02f, -8.69455620e-02f, - -8.64093225e-02f, -8.58627878e-02f, -8.53061837e-02f, -8.47394811e-02f, -8.41627464e-02f, -8.35761072e-02f, - -8.29796535e-02f, -8.23733932e-02f, -8.17574681e-02f, -8.11319028e-02f, -8.04968087e-02f, -7.98522496e-02f, - -7.91983230e-02f, -7.85350885e-02f, -7.78626591e-02f, -7.71811841e-02f, -7.64905893e-02f, -7.57910774e-02f, - -7.50826741e-02f, -7.43655714e-02f, -7.36397383e-02f, -7.29053493e-02f, -7.21624375e-02f, -7.14111558e-02f, - -7.06515842e-02f, -6.98837926e-02f, -6.91078824e-02f, -6.83239768e-02f, -6.75321390e-02f, -6.67325045e-02f, - -6.59251306e-02f, -6.51101501e-02f, -6.42876658e-02f, -6.34577804e-02f, -6.26205719e-02f, -6.17761852e-02f, - -6.09247081e-02f, -6.00662452e-02f, -5.92008862e-02f, -5.83287129e-02f, -5.74499401e-02f, -5.65646098e-02f, - -5.56728132e-02f, -5.47747143e-02f, -5.38703544e-02f, -5.29599299e-02f, -5.20435183e-02f, -5.11211134e-02f, - -5.01930675e-02f, -4.92593220e-02f, -4.83200573e-02f, -4.73753363e-02f, -4.64253333e-02f, -4.54701367e-02f, - -4.45099424e-02f, -4.35447089e-02f, -4.25746820e-02f, -4.15999546e-02f, -4.06206011e-02f, -3.96368223e-02f, - -3.86487047e-02f, -3.76563371e-02f, -3.66598667e-02f, -3.56594188e-02f, -3.46551403e-02f, -3.36471335e-02f, - -3.26354587e-02f, -3.16203603e-02f, -3.06018503e-02f, -2.95801739e-02f, -2.85553282e-02f, -2.75275089e-02f, - -2.64968550e-02f, -2.54634744e-02f, -2.44275268e-02f, -2.33890274e-02f, -2.23481859e-02f, -2.13051872e-02f, - -2.02600320e-02f, -1.92129794e-02f, -1.81640059e-02f, -1.71133703e-02f, -1.60611378e-02f, -1.50074416e-02f, - -1.39524596e-02f, -1.28962755e-02f, -1.18390029e-02f, -1.07807979e-02f, -9.72181068e-03f, -8.66211532e-03f, - -7.60192409e-03f, -6.54123772e-03f, -5.48027744e-03f, -4.41916170e-03f, -3.35802909e-03f, -2.29700489e-03f, - -1.23618422e-03f, -1.75676885e-04f, 8.84292956e-04f, 1.94365588e-03f, 3.00231168e-03f, 4.06004590e-03f, - 5.11684383e-03f, 6.17244320e-03f, 7.22689294e-03f, 8.27984747e-03f, 9.33139045e-03f, 1.03812699e-02f, - 1.14293764e-02f, 1.24755980e-02f, 1.35197918e-02f, 1.45618549e-02f, 1.56016492e-02f, 1.66390550e-02f, - 1.76739264e-02f, 1.87061866e-02f, 1.97356760e-02f, 2.07622658e-02f, 2.17857832e-02f, 2.28062623e-02f, - 2.38234334e-02f, 2.48372201e-02f, 2.58475057e-02f, 2.68541645e-02f, 2.78570634e-02f, 2.88560906e-02f, - 2.98511714e-02f, 3.08420835e-02f, 3.18288303e-02f, 3.28112208e-02f, 3.37890638e-02f, 3.47624356e-02f, - 3.57310553e-02f, 3.66949226e-02f, 3.76538040e-02f, 3.86076655e-02f, 3.95563268e-02f, 4.04997740e-02f, - 4.14378255e-02f, 4.23703945e-02f, 4.32973403e-02f, 4.42185369e-02f, 4.51339856e-02f, 4.60434355e-02f, - 4.69468700e-02f, 4.78441539e-02f, 4.87351829e-02f, 4.96198202e-02f, 5.04980334e-02f, 5.13696376e-02f, - 5.22346242e-02f, 5.30927845e-02f, 5.39440558e-02f, 5.47883446e-02f, 5.56256261e-02f, 5.64556814e-02f, - 5.72783999e-02f, 5.80938588e-02f, 5.89017483e-02f, 5.97021309e-02f, 6.04948122e-02f, 6.12797699e-02f, - 6.20568828e-02f, 6.28260518e-02f, 6.35871855e-02f, 6.43402076e-02f, 6.50850348e-02f, 6.58215381e-02f, - 6.65496997e-02f, 6.72694094e-02f, 6.79805332e-02f, 6.86830403e-02f, 6.93767923e-02f, 7.00618396e-02f, - 7.07379688e-02f, 7.14051182e-02f, 7.20632552e-02f, 7.27122641e-02f, 7.33521674e-02f, 7.39827419e-02f, - 7.46040446e-02f, 7.52158981e-02f, 7.58183314e-02f, 7.64111485e-02f, 7.69944013e-02f, 7.75679874e-02f, - 7.81318015e-02f, 7.86859073e-02f, 7.92299838e-02f, 7.97642559e-02f, 8.02884572e-02f, 8.08026802e-02f, - 8.13067156e-02f, 8.18006511e-02f, 8.22842900e-02f, 8.27577212e-02f, 8.32208044e-02f, 8.36734816e-02f, - 8.41157596e-02f, 8.45475000e-02f, 8.49687005e-02f, 8.53793895e-02f, 8.57794245e-02f, 8.61688068e-02f, - 8.65474225e-02f, 8.69152887e-02f, 8.72724443e-02f, 8.76187352e-02f, 8.79540918e-02f, 8.82785864e-02f, - 8.85921419e-02f, 8.88946983e-02f, 8.91862921e-02f, 8.94667943e-02f, 8.97362550e-02f, 8.99946163e-02f, - 9.02418653e-02f, 9.04779586e-02f, 9.07028676e-02f, 9.09165879e-02f, 9.11190632e-02f, 9.13103588e-02f, - 9.14903586e-02f, 9.16591159e-02f, 9.18165572e-02f, 9.19627155e-02f, 9.20975488e-02f, 9.22210408e-02f, - 9.23331949e-02f, 9.24340164e-02f, 9.25234936e-02f, 9.26015746e-02f, 9.26683592e-02f, 9.27237105e-02f, - 9.27676995e-02f, 9.28003816e-02f, 9.28215943e-02f, 9.28315189e-02f, 9.28300366e-02f, 9.28172241e-02f, - 9.27930394e-02f, 9.27575255e-02f, 9.27106435e-02f, 9.26524666e-02f, 9.25829714e-02f, 9.25021741e-02f, - 9.24100741e-02f, 9.23067331e-02f, 9.21921203e-02f, 9.20663267e-02f, 9.19292676e-02f, 9.17810261e-02f, - 9.16216235e-02f, 9.14510642e-02f, 9.12694045e-02f, 9.10766727e-02f, 9.08728356e-02f, 9.06579852e-02f, - 9.04321167e-02f, 9.01952927e-02f, 8.99475400e-02f, 8.96888889e-02f, 8.94193444e-02f, 8.91390021e-02f, - 8.88478623e-02f, 8.85459815e-02f, 8.82333956e-02f, 8.79101125e-02f, 8.75762299e-02f, 8.72317594e-02f, - 8.68768266e-02f, 8.65113755e-02f, 8.61354207e-02f, 8.57492074e-02f, 8.53525903e-02f, 8.49457312e-02f, - 8.45286216e-02f, 8.41013750e-02f, 8.36640310e-02f, 8.32165685e-02f, 8.27591688e-02f, 8.22917948e-02f, - 8.18146254e-02f, 8.13276225e-02f, 8.08308261e-02f, 8.03243545e-02f, 7.98083573e-02f, 7.92827189e-02f, - 7.87476821e-02f, 7.82031864e-02f, 7.76493461e-02f, 7.70862569e-02f, 7.65139964e-02f, 7.59325739e-02f, - 7.53421466e-02f, 7.47427499e-02f, 7.41344494e-02f, 7.35173552e-02f, 7.28914998e-02f, 7.22570297e-02f, - 7.16139819e-02f, 7.09624257e-02f, 7.03024714e-02f, 6.96342069e-02f, 6.89577007e-02f, 6.82730418e-02f, - 6.75803401e-02f, 6.68796470e-02f, 6.61710997e-02f, 6.54547628e-02f, 6.47306635e-02f, 6.39990402e-02f, - 6.32598546e-02f, 6.25132405e-02f, 6.17592912e-02f, 6.09981324e-02f, 6.02298311e-02f, 5.94545132e-02f, - 5.86722232e-02f, 5.78830983e-02f, 5.70872114e-02f, 5.62847435e-02f, 5.54756843e-02f, 5.46602280e-02f, - 5.38383697e-02f, 5.30103751e-02f, 5.21761415e-02f, 5.13359724e-02f, 5.04898370e-02f, 4.96379278e-02f, - 4.87803252e-02f, 4.79170459e-02f, 4.70483533e-02f, 4.61742513e-02f, 4.52949188e-02f, 4.44103788e-02f, - 4.35207739e-02f, 4.26262997e-02f, 4.17269397e-02f, 4.08229106e-02f, 3.99142896e-02f, 3.90011270e-02f, - 3.80836483e-02f, 3.71618873e-02f, 3.62359780e-02f, 3.53060246e-02f, 3.43721533e-02f, 3.34345616e-02f, - 3.24932188e-02f, 3.15483132e-02f, 3.06000495e-02f, 2.96483357e-02f, 2.86935455e-02f, 2.77355435e-02f, - 2.67746823e-02f, 2.58108802e-02f, 2.48443592e-02f, 2.38752570e-02f, 2.29036661e-02f, 2.19296784e-02f, - 2.09534291e-02f, 1.99751021e-02f, 1.89947558e-02f, 1.80124847e-02f, 1.70284543e-02f, 1.60428004e-02f, - 1.50556091e-02f, 1.40670508e-02f, 1.30771819e-02f, 1.20861492e-02f, 1.10941116e-02f, 1.01011317e-02f, - 9.10737240e-03f, 8.11296133e-03f, 7.11801095e-03f, 6.12260842e-03f, 5.12694964e-03f, 4.13105410e-03f, - 3.13512776e-03f, 2.13931673e-03f, 1.14362369e-03f, 1.48302464e-04f, -8.46631676e-04f, -1.84096645e-03f, - -2.83464431e-03f, -3.82750643e-03f, -4.81946886e-03f, -5.81037344e-03f, -6.80013280e-03f, -7.78856037e-03f, - -8.77560718e-03f, -9.76114098e-03f, -1.07449860e-02f, -1.17270961e-02f, -1.27073066e-02f, -1.36855333e-02f, - -1.46615707e-02f, -1.56353893e-02f, -1.66068427e-02f, -1.75758170e-02f, -1.85422081e-02f, -1.95058106e-02f, - -2.04666250e-02f, -2.14244935e-02f, -2.23792649e-02f, -2.33308537e-02f, -2.42791484e-02f, -2.52240114e-02f, - -2.61653347e-02f, -2.71029885e-02f, -2.80369377e-02f, -2.89669896e-02f, -2.98930203e-02f, -3.08150144e-02f, - -3.17327225e-02f, -3.26461473e-02f, -3.35551604e-02f, -3.44595510e-02f, -3.53593338e-02f, -3.62543976e-02f, - -3.71445363e-02f, -3.80297199e-02f, -3.89097716e-02f, -3.97846586e-02f, -4.06543015e-02f, -4.15185243e-02f, - -4.23771686e-02f, -4.32302240e-02f, -4.40775962e-02f, -4.49191633e-02f, -4.57547953e-02f, -4.65844231e-02f, - -4.74079686e-02f, -4.82252313e-02f, -4.90362095e-02f, -4.98407554e-02f, -5.06388539e-02f, -5.14303030e-02f, - -5.22150433e-02f, -5.29930603e-02f, -5.37641387e-02f, -5.45282581e-02f, -5.52853150e-02f, -5.60351679e-02f, - -5.67778561e-02f, -5.75131651e-02f, -5.82410403e-02f, -5.89614369e-02f, -5.96742381e-02f, -6.03793244e-02f, - -6.10766631e-02f, -6.17661469e-02f, -6.24477400e-02f, -6.31212835e-02f, -6.37867807e-02f, -6.44440852e-02f, - -6.50931657e-02f, -6.57339016e-02f, -6.63662452e-02f, -6.69901265e-02f, -6.76054610e-02f, -6.82121608e-02f, - -6.88102186e-02f, -6.93994838e-02f, -6.99799371e-02f, -7.05514859e-02f, -7.11140848e-02f, -7.16676629e-02f, - -7.22121041e-02f, -7.27474430e-02f, -7.32735492e-02f, -7.37903655e-02f, -7.42978575e-02f, -7.47959485e-02f, - -7.52845771e-02f, -7.57637193e-02f, -7.62332738e-02f, -7.66932147e-02f, -7.71435020e-02f, -7.75840684e-02f, - -7.80148620e-02f, -7.84357670e-02f, -7.88468057e-02f, -7.92480233e-02f, -7.96392041e-02f, -8.00204226e-02f, - -8.03915494e-02f, -8.07525860e-02f, -8.11035494e-02f, -8.14442484e-02f, -8.17748396e-02f, -8.20951088e-02f, - -8.24051207e-02f, -8.27048630e-02f, -8.29941724e-02f, -8.32731707e-02f, -8.35417206e-02f, -8.37998853e-02f, - -8.40475067e-02f, -8.42846962e-02f, -8.45113570e-02f, -8.47274759e-02f, -8.49330597e-02f, -8.51279882e-02f, - -8.53123857e-02f, -8.54861082e-02f, -8.56492333e-02f, -8.58016800e-02f, -8.59434730e-02f, -8.60746091e-02f, - -8.61949820e-02f, -8.63047207e-02f, -8.64036982e-02f, -8.64919921e-02f, -8.65695414e-02f, -8.66363446e-02f, - -8.66924477e-02f, -8.67377603e-02f, -8.67723675e-02f, -8.67962500e-02f, -8.68093596e-02f, -8.68117742e-02f, - -8.68034381e-02f, -8.67843711e-02f, -8.67545914e-02f, -8.67140620e-02f, -8.66629171e-02f, -8.66009787e-02f, - -8.65284460e-02f, -8.64451950e-02f, -8.63513207e-02f, -8.62468394e-02f, -8.61316810e-02f, -8.60060135e-02f, - -8.58696231e-02f, -8.57227895e-02f, -8.55653951e-02f, -8.53975015e-02f, -8.52191133e-02f, -8.50302399e-02f, - -8.48309474e-02f, -8.46212657e-02f, -8.44012058e-02f, -8.41708200e-02f, -8.39301121e-02f, -8.36791308e-02f, - -8.34178792e-02f, -8.31464628e-02f, -8.28648854e-02f, -8.25731633e-02f, -8.22713614e-02f, -8.19595132e-02f, - -8.16376713e-02f, -8.13058535e-02f, -8.09641574e-02f, -8.06125649e-02f, -8.02511436e-02f, -7.98800205e-02f, - -7.94990686e-02f, -7.91085496e-02f, -7.87083910e-02f, -7.82986385e-02f, -7.78793856e-02f, -7.74507010e-02f, - -7.70125919e-02f, -7.65651996e-02f, -7.61084506e-02f, -7.56425205e-02f, -7.51674576e-02f, -7.46832739e-02f, - -7.41900819e-02f, -7.36878726e-02f, -7.31768240e-02f, -7.26568998e-02f, -7.21282457e-02f, -7.15908686e-02f, - -7.10449031e-02f, -7.04903531e-02f, -6.99273045e-02f, -6.93558886e-02f, -6.87760899e-02f, -6.81880643e-02f, - -6.75918599e-02f, -6.69875231e-02f, -6.63751811e-02f, -6.57548533e-02f, -6.51267114e-02f, -6.44906975e-02f, - -6.38471323e-02f, -6.31957656e-02f, -6.25369804e-02f, -6.18706634e-02f, -6.11970178e-02f, -6.05160815e-02f, - -5.98279288e-02f, -5.91327352e-02f, -5.84304450e-02f, -5.77212782e-02f, -5.70052186e-02f, -5.62825050e-02f, - -5.55530557e-02f, -5.48170567e-02f, -5.40745648e-02f, -5.33257620e-02f, -5.25706547e-02f, -5.18093732e-02f, - -5.10420052e-02f, -5.02686514e-02f, -4.94893791e-02f, -4.87043635e-02f, -4.79136265e-02f, -4.71173110e-02f, - -4.63155130e-02f, -4.55083111e-02f, -4.46958197e-02f, -4.38781890e-02f, -4.30554303e-02f, -4.22277124e-02f, - -4.13951187e-02f, -4.05577549e-02f, -3.97157916e-02f, -3.88692325e-02f, -3.80181808e-02f, -3.71628535e-02f, - -3.63032736e-02f, -3.54395433e-02f, -3.45718463e-02f, -3.37002356e-02f, -3.28248043e-02f, -3.19457054e-02f, - -3.10630332e-02f, -3.01768872e-02f, -2.92874009e-02f, -2.83946443e-02f, -2.74987942e-02f, -2.65999043e-02f, - -2.56981200e-02f, -2.47935302e-02f, -2.38863285e-02f, -2.29764775e-02f, -2.20642057e-02f, -2.11496033e-02f, - -2.02328042e-02f, -1.93138200e-02f, -1.83929144e-02f, -1.74701315e-02f, -1.65455102e-02f, -1.56193654e-02f, - -1.46915767e-02f, -1.37624253e-02f, -1.28319871e-02f, -1.19002980e-02f, -1.09676491e-02f, -1.00339474e-02f, - -9.09947404e-03f, -8.16423477e-03f, -7.22842901e-03f, -6.29210227e-03f, -5.35543263e-03f, -4.41852947e-03f, - -3.48146503e-03f, -2.54437114e-03f, -1.60735363e-03f, -6.70598648e-04f, 2.65851663e-04f, 1.20187201e-03f, - 2.13734240e-03f, 3.07203450e-03f, 4.00608970e-03f, 4.93913757e-03f, 5.87124087e-03f, 6.80211869e-03f, - 7.73178419e-03f, 8.66003951e-03f, 9.58691297e-03f, 1.05121012e-02f, 1.14355869e-02f, 1.23572591e-02f, - 1.32770503e-02f, 1.41947113e-02f, 1.51102370e-02f, 1.60234456e-02f, 1.69343543e-02f, 1.78427144e-02f, - 1.87484257e-02f, 1.96514451e-02f, 2.05515870e-02f, 2.14488685e-02f, 2.23430193e-02f, 2.32340399e-02f, - 2.41217510e-02f, 2.50061043e-02f, 2.58869230e-02f, 2.67642274e-02f, 2.76376964e-02f, 2.85074503e-02f, - 2.93732107e-02f, 3.02350506e-02f, 3.10926263e-02f, 3.19460308e-02f, 3.27950742e-02f, 3.36396933e-02f, - 3.44797658e-02f, 3.53151665e-02f, 3.61457829e-02f, 3.69716011e-02f, 3.77923999e-02f, 3.86081809e-02f, - 3.94187791e-02f, 4.02241788e-02f, 4.10241965e-02f, 4.18187601e-02f, 4.26077703e-02f, 4.33911561e-02f, - 4.41687428e-02f, 4.49405845e-02f, 4.57064472e-02f, 4.64663198e-02f, 4.72200644e-02f, 4.79676433e-02f, - 4.87088900e-02f, 4.94437664e-02f, 5.01721752e-02f, 5.08940214e-02f, 5.16092357e-02f, 5.23176723e-02f, - 5.30193602e-02f, 5.37141300e-02f, 5.44019020e-02f, 5.50825977e-02f, 5.57561304e-02f, 5.64224954e-02f, - 5.70814835e-02f, 5.77331042e-02f, 5.83772822e-02f, 5.90139034e-02f, 5.96428632e-02f, 6.02642101e-02f, - 6.08777488e-02f, 6.14833911e-02f, 6.20811867e-02f, 6.26709800e-02f, 6.32527374e-02f, 6.38262989e-02f, - 6.43917005e-02f, 6.49488984e-02f, 6.54977528e-02f, 6.60381426e-02f, 6.65701154e-02f, 6.70935722e-02f, - 6.76085011e-02f, 6.81147431e-02f, 6.86122735e-02f, 6.91010578e-02f, 6.95810403e-02f, 7.00521226e-02f, - 7.05143088e-02f, 7.09675098e-02f, 7.14116745e-02f, 7.18467172e-02f, 7.22726910e-02f, 7.26894541e-02f, - 7.30969822e-02f, 7.34952172e-02f, 7.38841228e-02f, 7.42636945e-02f, 7.46338434e-02f, 7.49944776e-02f, - 7.53456866e-02f, 7.56873431e-02f, 7.60194097e-02f, 7.63418612e-02f, 7.66546741e-02f, 7.69578033e-02f, - 7.72512412e-02f, 7.75348378e-02f, 7.78087163e-02f, 7.80728178e-02f, 7.83270500e-02f, 7.85713789e-02f, - 7.88058411e-02f, 7.90303820e-02f, 7.92449566e-02f, 7.94495652e-02f, 7.96442138e-02f, 7.98288579e-02f, - 8.00034605e-02f, 8.01680374e-02f, 8.03224949e-02f, 8.04669300e-02f, 8.06012173e-02f, 8.07254932e-02f, - 8.08396104e-02f, 8.09435236e-02f, 8.10374021e-02f, 8.11210668e-02f, 8.11946539e-02f, 8.12580752e-02f, - 8.13113017e-02f, 8.13544190e-02f, 8.13872796e-02f, 8.14100800e-02f, 8.14226755e-02f, 8.14251754e-02f, - 8.14174554e-02f, 8.13995687e-02f, 8.13716054e-02f, 8.13334434e-02f, 8.12851979e-02f, 8.12268241e-02f, - 8.11583874e-02f, 8.10797822e-02f, 8.09911460e-02f, 8.08924365e-02f, 8.07836808e-02f, 8.06649134e-02f, - 8.05361109e-02f, 8.03973549e-02f, 8.02485968e-02f, 8.00899281e-02f, 7.99212591e-02f, 7.97427442e-02f, - 7.95544015e-02f, 7.93561723e-02f, 7.91481052e-02f, 7.89303046e-02f, 7.87027173e-02f, 7.84653924e-02f, - 7.82184255e-02f, 7.79617728e-02f, 7.76955071e-02f, 7.74196895e-02f, 7.71343013e-02f, 7.68393983e-02f, - 7.65350538e-02f, 7.62213084e-02f, 7.58981615e-02f, 7.55656891e-02f, 7.52239180e-02f, 7.48728743e-02f, - 7.45126855e-02f, 7.41433734e-02f, 7.37649436e-02f, 7.33773997e-02f, 7.29809569e-02f, 7.25755075e-02f, - 7.21612417e-02f, 7.17380986e-02f, 7.13061812e-02f, 7.08655483e-02f, 7.04162393e-02f, 6.99583789e-02f, - 6.94919458e-02f, 6.90170693e-02f, 6.85337538e-02f, 6.80420943e-02f, 6.75421504e-02f, 6.70339653e-02f, - 6.65176399e-02f, 6.59932741e-02f, 6.54608078e-02f, 6.49204691e-02f, 6.43722081e-02f, 6.38161719e-02f, - 6.32523797e-02f, 6.26809375e-02f, 6.21019172e-02f, 6.15153918e-02f, 6.09214195e-02f, 6.03200921e-02f, - 5.97115055e-02f, 5.90956989e-02f, 5.84728000e-02f, 5.78428170e-02f, 5.72059207e-02f, 5.65621234e-02f, - 5.59116003e-02f, 5.52542484e-02f, 5.45903622e-02f, 5.39199255e-02f, 5.32430418e-02f, 5.25597511e-02f, - 5.18702340e-02f, 5.11745452e-02f, 5.04726682e-02f, 4.97648913e-02f, 4.90511144e-02f, 4.83315895e-02f, - 4.76062524e-02f, 4.68753366e-02f, 4.61388550e-02f, 4.53968751e-02f, 4.46495897e-02f, 4.38970349e-02f, - 4.31393389e-02f, 4.23765245e-02f, 4.16087552e-02f, 4.08361300e-02f, 4.00586833e-02f, 3.92766337e-02f, - 3.84899672e-02f, 3.76988162e-02f, 3.69032733e-02f, 3.61034602e-02f, 3.52995217e-02f, 3.44915400e-02f, - 3.36794624e-02f, 3.28636309e-02f, 3.20439715e-02f, 3.12206861e-02f, 3.03938479e-02f, 2.95635399e-02f, - 2.87299103e-02f, 2.78930136e-02f, 2.70530617e-02f, 2.62100009e-02f, 2.53640493e-02f, 2.45152764e-02f, - 2.36638275e-02f, 2.28097675e-02f, 2.19532118e-02f, 2.10942899e-02f, 2.02330461e-02f, 1.93697066e-02f, - 1.85042439e-02f, 1.76368605e-02f, 1.67676759e-02f, 1.58966914e-02f, 1.50241637e-02f, 1.41500762e-02f, - 1.32746327e-02f, 1.23978732e-02f, 1.15199507e-02f, 1.06409445e-02f, 9.76096256e-03f, 8.88016497e-03f, - 7.99859851e-03f, 7.11642239e-03f, 6.23376075e-03f, 5.35069153e-03f, 4.46727062e-03f, 3.58374111e-03f, - 2.70003108e-03f, 1.81646541e-03f, 9.32987088e-04f, 4.98182424e-05f, -8.33010138e-04f, -1.71535574e-03f, - -2.59714745e-03f, -3.47824684e-03f, -4.35845095e-03f, -5.23779498e-03f, -6.11608277e-03f, -6.99324424e-03f, - -7.86916327e-03f, -8.74376580e-03f, -9.61684308e-03f, -1.04883694e-02f, -1.13581982e-02f, -1.22262520e-02f, - -1.30923975e-02f, -1.39565191e-02f, -1.48185614e-02f, -1.56783930e-02f, -1.65358244e-02f, -1.73908885e-02f, - -1.82433586e-02f, -1.90932820e-02f, -1.99403533e-02f, -2.07846157e-02f, -2.16258917e-02f, -2.24641012e-02f, - -2.32991622e-02f, -2.41309298e-02f, -2.49593566e-02f, -2.57842949e-02f, -2.66056357e-02f, -2.74232842e-02f, - -2.82371925e-02f, -2.90471606e-02f, -2.98532004e-02f, -3.06551547e-02f, -3.14528919e-02f, -3.22464068e-02f, - -3.30354819e-02f, -3.38201233e-02f, -3.46001688e-02f, -3.53755740e-02f, -3.61461939e-02f, -3.69120109e-02f, - -3.76728239e-02f, -3.84285815e-02f, -3.91792061e-02f, -3.99246772e-02f, -4.06647747e-02f, -4.13994756e-02f, - -4.21286408e-02f, -4.28522492e-02f, -4.35701876e-02f, -4.42823129e-02f, -4.49886675e-02f, -4.56890160e-02f, - -4.63833812e-02f, -4.70716071e-02f, -4.77536438e-02f, -4.84294183e-02f, -4.90988138e-02f, -4.97617882e-02f, - -5.04182775e-02f, -5.10681090e-02f, -5.17113167e-02f, -5.23477164e-02f, -5.29773454e-02f, -5.35999875e-02f, - -5.42156976e-02f, -5.48243186e-02f, -5.54258284e-02f, -5.60201323e-02f, -5.66071382e-02f, -5.71868228e-02f, - -5.77590919e-02f, -5.83238779e-02f, -5.88810861e-02f, -5.94306770e-02f, -5.99725834e-02f, -6.05067914e-02f, - -6.10330946e-02f, -6.15515588e-02f, -6.20620756e-02f, -6.25646199e-02f, -6.30591014e-02f, -6.35454004e-02f, - -6.40235953e-02f, -6.44935354e-02f, -6.49551497e-02f, -6.54084710e-02f, -6.58533501e-02f, -6.62898305e-02f, - -6.67177317e-02f, -6.71371611e-02f, -6.75479499e-02f, -6.79501001e-02f, -6.83435336e-02f, -6.87282228e-02f, - -6.91041572e-02f, -6.94712239e-02f, -6.98294292e-02f, -7.01787568e-02f, -7.05190806e-02f, -7.08503982e-02f, - -7.11726988e-02f, -7.14859966e-02f, -7.17900906e-02f, -7.20851088e-02f, -7.23709203e-02f, -7.26475153e-02f, - -7.29149204e-02f, -7.31730353e-02f, -7.34218490e-02f, -7.36613444e-02f, -7.38914713e-02f, -7.41122550e-02f, - -7.43235939e-02f, -7.45255757e-02f, -7.47180861e-02f, -7.49011573e-02f, -7.50746806e-02f, -7.52387039e-02f, - -7.53932978e-02f, -7.55382689e-02f, -7.56737609e-02f, -7.57996503e-02f, -7.59159591e-02f, -7.60226978e-02f, - -7.61198579e-02f, -7.62074010e-02f, -7.62853377e-02f, -7.63536728e-02f, -7.64123934e-02f, -7.64614496e-02f, - -7.65008919e-02f, -7.65306791e-02f, -7.65509007e-02f, -7.65614878e-02f, -7.65624597e-02f, -7.65537544e-02f, - -7.65354966e-02f, -7.65075451e-02f, -7.64700810e-02f, -7.64229791e-02f, -7.63663204e-02f, -7.63000862e-02f, - -7.62242447e-02f, -7.61389452e-02f, -7.60439903e-02f, -7.59395930e-02f, -7.58257158e-02f, -7.57023175e-02f, - -7.55694612e-02f, -7.54271817e-02f, -7.52754597e-02f, -7.51143527e-02f, -7.49438707e-02f, -7.47640271e-02f, - -7.45749082e-02f, -7.43764271e-02f, -7.41687122e-02f, -7.39517261e-02f, -7.37255732e-02f, -7.34902222e-02f, - -7.32457909e-02f, -7.29921592e-02f, -7.27295302e-02f, -7.24578010e-02f, -7.21771532e-02f, -7.18875044e-02f, - -7.15889239e-02f, -7.12814852e-02f, -7.09651828e-02f, -7.06401326e-02f, -7.03063020e-02f, -6.99638239e-02f, - -6.96126165e-02f, -6.92528124e-02f, -6.88844920e-02f, -6.85076439e-02f, -6.81223248e-02f, -6.77285784e-02f, - -6.73265288e-02f, -6.69161812e-02f, -6.64975412e-02f, -6.60707272e-02f, -6.56357602e-02f, -6.51927328e-02f, - -6.47417002e-02f, -6.42827266e-02f, -6.38157790e-02f, -6.33411029e-02f, -6.28585932e-02f, -6.23683940e-02f, - -6.18705486e-02f, -6.13651196e-02f, -6.08521815e-02f, -6.03318069e-02f, -5.98040785e-02f, -5.92690001e-02f, - -5.87266930e-02f, -5.81772131e-02f, -5.76206948e-02f, -5.70570997e-02f, -5.64866058e-02f, -5.59091910e-02f, - -5.53250256e-02f, -5.47341162e-02f, -5.41365529e-02f, -5.35324553e-02f, -5.29218279e-02f, -5.23048368e-02f, - -5.16814969e-02f, -5.10519173e-02f, -5.04161721e-02f, -4.97743036e-02f, -4.91264932e-02f, -4.84727794e-02f, - -4.78131759e-02f, -4.71478540e-02f, -4.64768605e-02f, -4.58002882e-02f, -4.51183195e-02f, -4.44308222e-02f, - -4.37381008e-02f, -4.30401182e-02f, -4.23370184e-02f, -4.16289050e-02f, -4.09158156e-02f, -4.01978531e-02f, - -3.94751658e-02f, -3.87477949e-02f, -3.80157923e-02f, -3.72793898e-02f, -3.65385680e-02f, -3.57934461e-02f, - -3.50441121e-02f, -3.42906461e-02f, -3.35332703e-02f, -3.27719034e-02f, -3.20067744e-02f, -3.12378653e-02f, - -3.04654091e-02f, -2.96893881e-02f, -2.89099477e-02f, -2.81272362e-02f, -2.73412773e-02f, -2.65521643e-02f, - -2.57600934e-02f, -2.49650479e-02f, -2.41672551e-02f, -2.33666739e-02f, -2.25635346e-02f, -2.17578604e-02f, - -2.09497725e-02f, -2.01393913e-02f, -1.93267972e-02f, -1.85121366e-02f, -1.76954332e-02f, -1.68768603e-02f, - -1.60565190e-02f, -1.52344622e-02f, -1.44108002e-02f, -1.35857281e-02f, -1.27592381e-02f, -1.19315357e-02f, - -1.11026017e-02f, -1.02726448e-02f, -9.44169936e-03f, -8.60999732e-03f, -7.77749355e-03f, -6.94434744e-03f, - -6.11068648e-03f, -5.27658877e-03f, -4.44218083e-03f, -3.60751626e-03f, -2.77280372e-03f, -1.93806536e-03f, - -1.10341883e-03f, -2.68960890e-04f, 5.65143488e-04f, 1.39887705e-03f, 2.23203756e-03f, 3.06461778e-03f, - 3.89644329e-03f, 4.72745631e-03f, 5.55753120e-03f, 6.38652850e-03f, 7.21441633e-03f, 8.04101919e-03f, - 8.86631432e-03f, 9.69008490e-03f, 1.05123627e-02f, 1.13329552e-02f, 1.21517407e-02f, 1.29686729e-02f, - 1.37836570e-02f, 1.45965526e-02f, 1.54072674e-02f, 1.62157052e-02f, 1.70218183e-02f, 1.78253357e-02f, - 1.86264017e-02f, 1.94246844e-02f, 2.02202295e-02f, 2.10129106e-02f, 2.18025997e-02f, 2.25891876e-02f, - 2.33726609e-02f, 2.41528450e-02f, 2.49296056e-02f, 2.57029581e-02f, 2.64727335e-02f, 2.72388125e-02f, - 2.80011849e-02f, 2.87597166e-02f, 2.95142966e-02f, 3.02648468e-02f, 3.10112305e-02f, 3.17534437e-02f, - 3.24913180e-02f, 3.32247952e-02f, 3.39537692e-02f, 3.46781562e-02f, 3.53978841e-02f, 3.61128380e-02f, - 3.68229460e-02f, 3.75280932e-02f, 3.82282562e-02f, 3.89232678e-02f, 3.96130736e-02f, 4.02976299e-02f, - 4.09767896e-02f, 4.16505209e-02f, 4.23187236e-02f, 4.29812780e-02f, 4.36381665e-02f, 4.42892273e-02f, - 4.49344881e-02f, 4.55737591e-02f, 4.62070323e-02f, 4.68342084e-02f, 4.74552219e-02f, 4.80700190e-02f, - 4.86784229e-02f, 4.92804821e-02f, 4.98760256e-02f, 5.04651148e-02f, 5.10475055e-02f, 5.16232448e-02f, - 5.21922120e-02f, 5.27543222e-02f, 5.33095902e-02f, 5.38579194e-02f, 5.43991807e-02f, 5.49333494e-02f, - 5.54603699e-02f, 5.59801858e-02f, 5.64926529e-02f, 5.69978385e-02f, 5.74956121e-02f, 5.79858936e-02f, - 5.84686623e-02f, 5.89438356e-02f, 5.94113976e-02f, 5.98711994e-02f, 6.03233355e-02f, 6.07675811e-02f, - 6.12040359e-02f, 6.16325283e-02f, 6.20530699e-02f, 6.24656110e-02f, 6.28700989e-02f, 6.32664668e-02f, - 6.36546673e-02f, 6.40346678e-02f, 6.44064369e-02f, 6.47699089e-02f, 6.51250215e-02f, 6.54717720e-02f, - 6.58101244e-02f, 6.61400240e-02f, 6.64613738e-02f, 6.67742813e-02f, 6.70785552e-02f, 6.73742576e-02f, - 6.76612586e-02f, 6.79396670e-02f, 6.82093574e-02f, 6.84702831e-02f, 6.87225047e-02f, 6.89658686e-02f, - 6.92004629e-02f, 6.94261818e-02f, 6.96430472e-02f, 6.98510262e-02f, 7.00501014e-02f, 7.02401719e-02f, - 7.04213494e-02f, 7.05935177e-02f, 7.07567282e-02f, 7.09108728e-02f, 7.10560139e-02f, 7.11921140e-02f, - 7.13191502e-02f, 7.14371424e-02f, 7.15460473e-02f, 7.16458158e-02f, 7.17364926e-02f, 7.18180943e-02f, - 7.18905504e-02f, 7.19539117e-02f, 7.20081080e-02f, 7.20532320e-02f, 7.20891819e-02f, 7.21160170e-02f, - 7.21336838e-02f, 7.21422436e-02f, 7.21416905e-02f, 7.21319970e-02f, 7.21131869e-02f, 7.20852557e-02f, - 7.20482561e-02f, 7.20020878e-02f, 7.19468520e-02f, 7.18825709e-02f, 7.18091905e-02f, 7.17267627e-02f, - 7.16352986e-02f, 7.15348027e-02f, 7.14252790e-02f, 7.13068109e-02f, 7.11793430e-02f, 7.10428923e-02f, - 7.08975672e-02f, 7.07432301e-02f, 7.05800890e-02f, 7.04081070e-02f, 7.02271909e-02f, 7.00375528e-02f, - 6.98390491e-02f, 6.96318273e-02f, 6.94158914e-02f, 6.91912275e-02f, 6.89579376e-02f, 6.87159470e-02f, - 6.84654277e-02f, 6.82062739e-02f, 6.79386445e-02f, 6.76625437e-02f, 6.73779084e-02f, 6.70849391e-02f, - 6.67835587e-02f, 6.64738935e-02f, 6.61558871e-02f, 6.58296200e-02f, 6.54951676e-02f, 6.51526233e-02f, - 6.48019100e-02f, 6.44431239e-02f, 6.40763498e-02f, 6.37015567e-02f, 6.33189473e-02f, 6.29284072e-02f, - 6.25301017e-02f, 6.21239812e-02f, 6.17102251e-02f, 6.12887412e-02f, 6.08597672e-02f, 6.04231896e-02f, - 5.99791756e-02f, 5.95276933e-02f, 5.90689279e-02f, 5.86027733e-02f, 5.81294676e-02f, 5.76489708e-02f, - 5.71613886e-02f, 5.66667071e-02f, 5.61650808e-02f, 5.56565539e-02f, 5.51411496e-02f, 5.46190123e-02f, - 5.40901305e-02f, 5.35546375e-02f, 5.30125531e-02f, 5.24639846e-02f, 5.19089997e-02f, 5.13476613e-02f, - 5.07800523e-02f, 5.02062043e-02f, 4.96262561e-02f, 4.90402926e-02f, 4.84483047e-02f, 4.78503972e-02f, - 4.72467095e-02f, 4.66372609e-02f, 4.60221693e-02f, 4.54014753e-02f, 4.47752976e-02f, 4.41436481e-02f, - 4.35067401e-02f, 4.28645507e-02f, 4.22171365e-02f, 4.15646791e-02f, 4.09072182e-02f, 4.02448452e-02f, - 3.95776183e-02f, 3.89056525e-02f, 3.82290190e-02f, 3.75478382e-02f, 3.68621450e-02f, 3.61721137e-02f, - 3.54776664e-02f, 3.47791260e-02f, 3.40763727e-02f, 3.33696318e-02f, 3.26588994e-02f, 3.19443836e-02f, - 3.12260436e-02f, 3.05040749e-02f, 2.97784933e-02f, 2.90494935e-02f, 2.83170343e-02f, 2.75813161e-02f, - 2.68423491e-02f, 2.61003587e-02f, 2.53553034e-02f, 2.46073738e-02f, 2.38566259e-02f, 2.31030759e-02f, - 2.23469952e-02f, 2.15883320e-02f, 2.08272733e-02f, 2.00638158e-02f, 1.92981784e-02f, 1.85304166e-02f, - 1.77606130e-02f, 1.69888248e-02f, 1.62151823e-02f, 1.54398759e-02f, 1.46628480e-02f, 1.38843222e-02f, - 1.31043229e-02f, 1.23229450e-02f, 1.15404068e-02f, 1.07566189e-02f, 9.97185422e-03f, 9.18610790e-03f, - 8.39954045e-03f, 7.61220973e-03f, 6.82424135e-03f, 6.03571273e-03f, 5.24671357e-03f, 4.45741059e-03f, - 3.66782417e-03f, 2.87812708e-03f, 2.08835931e-03f, 1.29864705e-03f, 5.09102815e-04f, -2.80214487e-04f, - -1.06916826e-03f, -1.85765646e-03f, -2.64558515e-03f, -3.43287664e-03f, -4.21946311e-03f, -5.00511916e-03f, - -5.78984766e-03f, -6.57352056e-03f, -7.35606260e-03f, -8.13732788e-03f, -8.91728000e-03f, -9.69574968e-03f, - -1.04727125e-02f, -1.12480231e-02f, -1.20215820e-02f, -1.27932901e-02f, -1.35630785e-02f, -1.43308690e-02f, - -1.50964659e-02f, -1.58599288e-02f, -1.66209605e-02f, -1.73796874e-02f, -1.81358169e-02f, -1.88893848e-02f, - -1.96402120e-02f, -2.03882239e-02f, -2.11334696e-02f, -2.18756333e-02f, -2.26147564e-02f, -2.33506649e-02f, - -2.40833847e-02f, -2.48126764e-02f, -2.55385678e-02f, -2.62608999e-02f, -2.69796530e-02f, -2.76946274e-02f, - -2.84058634e-02f, -2.91131486e-02f, -2.98164934e-02f, -3.05157442e-02f, -3.12108482e-02f, -3.19017305e-02f, - -3.25882475e-02f, -3.32703759e-02f, -3.39479696e-02f, -3.46210477e-02f, -3.52893597e-02f, -3.59529996e-02f, - -3.66117798e-02f, -3.72656453e-02f, -3.79145014e-02f, -3.85583045e-02f, -3.91969664e-02f, -3.98303453e-02f, - -4.04584479e-02f, -4.10811429e-02f, -4.16983408e-02f, -4.23100377e-02f, -4.29161179e-02f, -4.35164658e-02f, - -4.41111002e-02f, -4.46998241e-02f, -4.52826555e-02f, -4.58594685e-02f, -4.64303011e-02f, -4.69949736e-02f, - -4.75534336e-02f, -4.81056087e-02f, -4.86515072e-02f, -4.91909676e-02f, -4.97239437e-02f, -5.02504148e-02f, - -5.07702721e-02f, -5.12835039e-02f, -5.17899670e-02f, -5.22896657e-02f, -5.27825096e-02f, -5.32684468e-02f, - -5.37474585e-02f, -5.42193532e-02f, -5.46842828e-02f, -5.51420328e-02f, -5.55925482e-02f, -5.60358475e-02f, - -5.64718451e-02f, -5.69004969e-02f, -5.73217709e-02f, -5.77355191e-02f, -5.81418183e-02f, -5.85404903e-02f, - -5.89316957e-02f, -5.93151324e-02f, -5.96909102e-02f, -6.00589535e-02f, -6.04191914e-02f, -6.07716533e-02f, - -6.11162002e-02f, -6.14528472e-02f, -6.17815552e-02f, -6.21022952e-02f, -6.24149807e-02f, -6.27196008e-02f, - -6.30161663e-02f, -6.33045330e-02f, -6.35848043e-02f, -6.38567801e-02f, -6.41206313e-02f, -6.43761791e-02f, - -6.46234544e-02f, -6.48623758e-02f, -6.50929334e-02f, -6.53152029e-02f, -6.55290349e-02f, -6.57344472e-02f, - -6.59313883e-02f, -6.61199017e-02f, -6.62999155e-02f, -6.64714259e-02f, -6.66344048e-02f, -6.67888392e-02f, - -6.69347518e-02f, -6.70720359e-02f, -6.72007544e-02f, -6.73208972e-02f, -6.74324167e-02f, -6.75352965e-02f, - -6.76295621e-02f, -6.77151706e-02f, -6.77920919e-02f, -6.78604542e-02f, -6.79200391e-02f, -6.79710614e-02f, - -6.80133563e-02f, -6.80470172e-02f, -6.80719657e-02f, -6.80882469e-02f, -6.80958758e-02f, -6.80948557e-02f, - -6.80851057e-02f, -6.80667495e-02f, -6.80397335e-02f, -6.80040462e-02f, -6.79597526e-02f, -6.79067870e-02f, - -6.78452466e-02f, -6.77750273e-02f, -6.76962503e-02f, -6.76088946e-02f, -6.75129772e-02f, -6.74084852e-02f, - -6.72954323e-02f, -6.71739130e-02f, -6.70438471e-02f, -6.69053287e-02f, -6.67582995e-02f, -6.66029048e-02f, - -6.64390135e-02f, -6.62667965e-02f, -6.60861772e-02f, -6.58972254e-02f, -6.56999512e-02f, -6.54944095e-02f, - -6.52805733e-02f, -6.50585144e-02f, -6.48283029e-02f, -6.45899050e-02f, -6.43433963e-02f, -6.40887263e-02f, - -6.38261267e-02f, -6.35553611e-02f, -6.32766980e-02f, -6.29900524e-02f, -6.26954988e-02f, -6.23930720e-02f, - -6.20828541e-02f, -6.17648345e-02f, -6.14390937e-02f, -6.11056428e-02f, -6.07645304e-02f, -6.04157846e-02f, - -6.00595307e-02f, -5.96957705e-02f, -5.93245287e-02f, -5.89459304e-02f, -5.85598868e-02f, -5.81666099e-02f, - -5.77660535e-02f, -5.73582610e-02f, -5.69433805e-02f, -5.65213852e-02f, -5.60923763e-02f, -5.56563771e-02f, - -5.52134397e-02f, -5.47636872e-02f, -5.43071142e-02f, -5.38437943e-02f, -5.33737919e-02f, -5.28972006e-02f, - -5.24140423e-02f, -5.19244428e-02f, -5.14283872e-02f, -5.09259442e-02f, -5.04172437e-02f, -4.99022971e-02f, - -4.93812283e-02f, -4.88540765e-02f, -4.83208795e-02f, -4.77817587e-02f, -4.72367572e-02f, -4.66859540e-02f, - -4.61293714e-02f, -4.55671925e-02f, -4.49994243e-02f, -4.44261107e-02f, -4.38473915e-02f, -4.32633127e-02f, - -4.26739523e-02f, -4.20793576e-02f, -4.14796610e-02f, -4.08749203e-02f, -4.02651721e-02f, -3.96505907e-02f, - -3.90311224e-02f, -3.84069859e-02f, -3.77782048e-02f, -3.71448604e-02f, -3.65069060e-02f, -3.58647114e-02f, - -3.52181444e-02f, -3.45673464e-02f, -3.39123695e-02f, -3.32533520e-02f, -3.25903251e-02f, -3.19234730e-02f, - -3.12527426e-02f, -3.05783503e-02f, -2.99003107e-02f, -2.92186665e-02f, -2.85336553e-02f, -2.78452229e-02f, - -2.71535340e-02f, -2.64586573e-02f, -2.57606680e-02f, -2.50597033e-02f, -2.43557542e-02f, -2.36490016e-02f, - -2.29395392e-02f, -2.22274325e-02f, -2.15127687e-02f, -2.07956426e-02f, -2.00761351e-02f, -1.93543395e-02f, - -1.86303696e-02f, -1.79043302e-02f, -1.71762887e-02f, -1.64463352e-02f, -1.57145805e-02f, -1.49810735e-02f, - -1.42460234e-02f, -1.35093696e-02f, -1.27713131e-02f, -1.20319155e-02f, -1.12912864e-02f, -1.05495173e-02f, - -9.80667686e-03f, -9.06287603e-03f, -8.31820223e-03f, -7.57281937e-03f, -6.82671320e-03f, -6.08003741e-03f, - -5.33285145e-03f, -4.58535526e-03f, -3.83749910e-03f, -3.08950001e-03f, -2.34136964e-03f, -1.59325203e-03f, - -8.45250270e-04f, -9.73580819e-05f, 6.50174465e-04f, 1.39742074e-03f, 2.14404221e-03f, 2.89023434e-03f, - 3.63570177e-03f, 4.38041730e-03f, 5.12428953e-03f, 5.86720769e-03f, 6.60908491e-03f, 7.34982320e-03f, - 8.08933742e-03f, 8.82752258e-03f, 9.56429256e-03f, 1.02995513e-02f, 1.10332033e-02f, 1.17651454e-02f, - 1.24953127e-02f, 1.32236291e-02f, 1.39498824e-02f, 1.46741571e-02f, 1.53962426e-02f, 1.61160613e-02f, - 1.68335360e-02f, 1.75485770e-02f, 1.82611387e-02f, 1.89710457e-02f, 1.96783092e-02f, 2.03826805e-02f, - 2.10842525e-02f, 2.17828475e-02f, 2.24783646e-02f, 2.31707221e-02f, 2.38599000e-02f, 2.45457091e-02f, - 2.52281333e-02f, 2.59070988e-02f, 2.65824196e-02f, 2.72541351e-02f, 2.79220574e-02f, 2.85862096e-02f, - 2.92464206e-02f, 2.99026330e-02f, 3.05548058e-02f, 3.12027543e-02f, 3.18465187e-02f, 3.24859107e-02f, - 3.31209363e-02f, 3.37514787e-02f, 3.43774807e-02f, 3.49988083e-02f, 3.56154096e-02f, 3.62272688e-02f, - 3.68342559e-02f, 3.74362707e-02f, 3.80332432e-02f, 3.86251856e-02f, 3.92118793e-02f, 3.97934534e-02f, - 4.03695921e-02f, 4.09404067e-02f, 4.15057813e-02f, 4.20656131e-02f, 4.26198152e-02f, 4.31684033e-02f, - 4.37112313e-02f, 4.42482779e-02f, 4.47794298e-02f, 4.53046976e-02f, 4.58239635e-02f, 4.63371502e-02f, - 4.68441800e-02f, 4.73451084e-02f, 4.78396886e-02f, 4.83280602e-02f, 4.88099862e-02f, 4.92855393e-02f, - 4.97546189e-02f, 5.02170930e-02f, 5.06730029e-02f, 5.11222365e-02f, 5.15648157e-02f, 5.20005540e-02f, - 5.24295177e-02f, 5.28516182e-02f, 5.32667876e-02f, 5.36749605e-02f, 5.40761509e-02f, 5.44702629e-02f, - 5.48572793e-02f, 5.52370731e-02f, 5.56096850e-02f, 5.59750456e-02f, 5.63331155e-02f, 5.66838315e-02f, - 5.70271562e-02f, 5.73630777e-02f, 5.76915617e-02f, 5.80124454e-02f, 5.83258309e-02f, 5.86316876e-02f, - 5.89298968e-02f, 5.92204201e-02f, 5.95033179e-02f, 5.97784257e-02f, 6.00458101e-02f, 6.03054653e-02f, - 6.05572282e-02f, 6.08012305e-02f, 6.10372936e-02f, 6.12654744e-02f, 6.14857428e-02f, 6.16980643e-02f, - 6.19024028e-02f, 6.20987889e-02f, 6.22870509e-02f, 6.24673553e-02f, 6.26395882e-02f, 6.28037752e-02f, - 6.29597804e-02f, 6.31077571e-02f, 6.32475595e-02f, 6.33792367e-02f, 6.35027538e-02f, 6.36180385e-02f, - 6.37252381e-02f, 6.38241738e-02f, 6.39149275e-02f, 6.39975246e-02f, 6.40718161e-02f, 6.41379369e-02f, - 6.41957764e-02f, 6.42454617e-02f, 6.42868545e-02f, 6.43200321e-02f, 6.43449067e-02f, 6.43616196e-02f, - 6.43700293e-02f, 6.43702422e-02f, 6.43621859e-02f, 6.43459334e-02f, 6.43214122e-02f, 6.42887102e-02f, - 6.42477719e-02f, 6.41986561e-02f, 6.41413397e-02f, 6.40758375e-02f, 6.40021314e-02f, 6.39202582e-02f, - 6.38302864e-02f, 6.37321541e-02f, 6.36258851e-02f, 6.35115594e-02f, 6.33891295e-02f, 6.32586456e-02f, - 6.31200663e-02f, 6.29735358e-02f, 6.28189686e-02f, 6.26564120e-02f, 6.24859316e-02f, 6.23074612e-02f, - 6.21211593e-02f, 6.19269276e-02f, 6.17248842e-02f, 6.15149720e-02f, 6.12973086e-02f, 6.10718516e-02f, - 6.08386895e-02f, 6.05978191e-02f, 6.03492811e-02f, 6.00931403e-02f, 5.98293618e-02f, 5.95580889e-02f, - 5.92792353e-02f, 5.89929688e-02f, 5.86991719e-02f, 5.83980360e-02f, 5.80895424e-02f, 5.77737374e-02f, - 5.74506088e-02f, 5.71202910e-02f, 5.67827647e-02f, 5.64381405e-02f, 5.60863745e-02f, 5.57275891e-02f, - 5.53617976e-02f, 5.49891035e-02f, 5.46094638e-02f, 5.42230230e-02f, 5.38297273e-02f, 5.34297475e-02f, - 5.30230511e-02f, 5.26096940e-02f, 5.21898438e-02f, 5.17633853e-02f, 5.13305339e-02f, 5.08912465e-02f, - 5.04456369e-02f, 4.99936790e-02f, 4.95355514e-02f, 4.90712571e-02f, 4.86008058e-02f, 4.81243539e-02f, - 4.76419401e-02f, 4.71535805e-02f, 4.66594082e-02f, 4.61594003e-02f, 4.56536912e-02f, 4.51423474e-02f, - 4.46253958e-02f, 4.41029644e-02f, 4.35750545e-02f, 4.30417846e-02f, 4.25031975e-02f, 4.19594144e-02f, - 4.14103965e-02f, 4.08563519e-02f, 4.02972345e-02f, 3.97331959e-02f, 3.91643037e-02f, 3.85906096e-02f, - 3.80121844e-02f, 3.74291155e-02f, 3.68414800e-02f, 3.62493197e-02f, 3.56528022e-02f, 3.50519250e-02f, - 3.44467555e-02f, 3.38374798e-02f, 3.32240353e-02f, 3.26065913e-02f, 3.19852382e-02f, 3.13600278e-02f, - 3.07310000e-02f, 3.00982731e-02f, 2.94620264e-02f, 2.88221338e-02f, 2.81788761e-02f, 2.75322001e-02f, - 2.68822821e-02f, 2.62291785e-02f, 2.55729801e-02f, 2.49137056e-02f, 2.42515329e-02f, 2.35865066e-02f, - 2.29186725e-02f, 2.22482571e-02f, 2.15751466e-02f, 2.08996045e-02f, 2.02215874e-02f, 1.95412873e-02f, - 1.88587142e-02f, 1.81740119e-02f, 1.74872498e-02f, 1.67984883e-02f, 1.61078777e-02f, 1.54154300e-02f, - 1.47213082e-02f, 1.40255194e-02f, 1.33282612e-02f, 1.26295365e-02f, 1.19294485e-02f, 1.12281629e-02f, - 1.05256176e-02f, 9.82210635e-03f, 9.11750323e-03f, 8.41207839e-03f, 7.70578313e-03f, 6.99886232e-03f, - 6.29124550e-03f, 5.58311432e-03f, 4.87453353e-03f, 4.16563902e-03f, 3.45650712e-03f, 2.74713836e-03f, - 2.03771341e-03f, 1.32829064e-03f, 6.18974309e-04f, -9.00963923e-05f, -7.98925353e-04f, -1.50734202e-03f, - -2.21533812e-03f, -2.92274595e-03f, -3.62949395e-03f, -4.33552877e-03f, -5.04070797e-03f, -5.74497980e-03f, - -6.44824336e-03f, -7.15044582e-03f, -7.85138311e-03f, -8.55104285e-03f, -9.24938329e-03f, -9.94625967e-03f, - -1.06416041e-02f, -1.13352986e-02f, -1.20272264e-02f, -1.27173819e-02f, -1.34056262e-02f, -1.40918688e-02f, - -1.47761091e-02f, -1.54580901e-02f, -1.61379105e-02f, -1.68153346e-02f, -1.74903516e-02f, -1.81628963e-02f, - -1.88328111e-02f, -1.95000568e-02f, -2.01645694e-02f, -2.08262222e-02f, -2.14848790e-02f, -2.21406476e-02f, - -2.27932298e-02f, -2.34426723e-02f, -2.40887842e-02f, -2.47316587e-02f, -2.53710671e-02f, -2.60069741e-02f, - -2.66392821e-02f, -2.72679391e-02f, -2.78928540e-02f, -2.85139168e-02f, -2.91311187e-02f, -2.97443017e-02f, - -3.03534816e-02f, -3.09585072e-02f, -3.15593082e-02f, -3.21558261e-02f, -3.27480278e-02f, -3.33357403e-02f, - -3.39189763e-02f, -3.44976420e-02f, -3.50716101e-02f, -3.56408999e-02f, -3.62053796e-02f, -3.67649839e-02f, - -3.73196491e-02f, -3.78693134e-02f, -3.84139103e-02f, -3.89533924e-02f, -3.94875772e-02f, -4.00165707e-02f, - -4.05401905e-02f, -4.10584257e-02f, -4.15711315e-02f, -4.20783238e-02f, -4.25799326e-02f, -4.30759119e-02f, - -4.35661221e-02f, -4.40505263e-02f, -4.45291353e-02f, -4.50018063e-02f, -4.54685536e-02f, -4.59292562e-02f, - -4.63838841e-02f, -4.68323624e-02f, -4.72747201e-02f, -4.77107350e-02f, -4.81405267e-02f, -4.85639256e-02f, - -4.89809799e-02f, -4.93915499e-02f, -4.97956138e-02f, -5.01931094e-02f, -5.05840102e-02f, -5.09682949e-02f, - -5.13458353e-02f, -5.17166824e-02f, -5.20807117e-02f, -5.24379330e-02f, -5.27882885e-02f, -5.31316645e-02f, - -5.34681570e-02f, -5.37976172e-02f, -5.41200375e-02f, -5.44353955e-02f, -5.47436037e-02f, -5.50446883e-02f, - -5.53386109e-02f, -5.56252567e-02f, -5.59046479e-02f, -5.61767941e-02f, -5.64415792e-02f, -5.66990280e-02f, - -5.69490805e-02f, -5.71917231e-02f, -5.74269420e-02f, -5.76546619e-02f, -5.78749176e-02f, -5.80876156e-02f, - -5.82927702e-02f, -5.84903689e-02f, -5.86803914e-02f, -5.88627892e-02f, -5.90375388e-02f, -5.92046535e-02f, - -5.93640553e-02f, -5.95158220e-02f, -5.96598200e-02f, -5.97961538e-02f, -5.99247115e-02f, -6.00455346e-02f, - -6.01585684e-02f, -6.02638767e-02f, -6.03613668e-02f, -6.04510797e-02f, -6.05329340e-02f, -6.06070486e-02f, - -6.06732790e-02f, -6.07317477e-02f, -6.07823181e-02f, -6.08251296e-02f, -6.08600309e-02f, -6.08871775e-02f, - -6.09064160e-02f, -6.09178504e-02f, -6.09214317e-02f, -6.09172011e-02f, -6.09051492e-02f, -6.08852356e-02f, - -6.08574847e-02f, -6.08219930e-02f, -6.07786544e-02f, -6.07275317e-02f, -6.06685868e-02f, -6.06018748e-02f, - -6.05274309e-02f, -6.04452200e-02f, -6.03552736e-02f, -6.02575414e-02f, -6.01521679e-02f, -6.00390613e-02f, - -5.99183128e-02f, -5.97898644e-02f, -5.96538444e-02f, -5.95101127e-02f, -5.93588782e-02f, -5.91999915e-02f, - -5.90335914e-02f, -5.88596413e-02f, -5.86782154e-02f, -5.84892941e-02f, -5.82929075e-02f, -5.80891426e-02f, - -5.78779549e-02f, -5.76594564e-02f, -5.74335576e-02f, -5.72003744e-02f, -5.69599167e-02f, -5.67122685e-02f, - -5.64573853e-02f, -5.61953271e-02f, -5.59261654e-02f, -5.56499066e-02f, -5.53666104e-02f, -5.50762774e-02f, - -5.47790113e-02f, -5.44747614e-02f, -5.41636345e-02f, -5.38456802e-02f, -5.35209043e-02f, -5.31893920e-02f, - -5.28511213e-02f, -5.25062169e-02f, -5.21546489e-02f, -5.17965521e-02f, -5.14319252e-02f, -5.10607691e-02f, - -5.06832514e-02f, -5.02993183e-02f, -4.99090854e-02f, -4.95125668e-02f, -4.91098562e-02f, -4.87009071e-02f, - -4.82859290e-02f, -4.78648620e-02f, -4.74377835e-02f, -4.70047966e-02f, -4.65658836e-02f, -4.61212332e-02f, - -4.56707136e-02f, -4.52145855e-02f, -4.47527289e-02f, -4.42853534e-02f, -4.38124055e-02f, -4.33340570e-02f, - -4.28502440e-02f, -4.23611776e-02f, -4.18668136e-02f, -4.13672068e-02f, -4.08625630e-02f, -4.03527826e-02f, - -3.98380474e-02f, -3.93183195e-02f, -3.87938139e-02f, -3.82644325e-02f, -3.77303807e-02f, -3.71916389e-02f, - -3.66483542e-02f, -3.61005557e-02f, -3.55483277e-02f, -3.49917166e-02f, -3.44308292e-02f, -3.38656882e-02f, - -3.32964284e-02f, -3.27230957e-02f, -3.21458051e-02f, -3.15645726e-02f, -3.09794831e-02f, -3.03906058e-02f, - -2.97981363e-02f, -2.92019666e-02f, -2.86023315e-02f, -2.79991842e-02f, -2.73926899e-02f, -2.67829066e-02f, - -2.61699117e-02f, -2.55537749e-02f, -2.49345690e-02f, -2.43124123e-02f, -2.36873489e-02f, -2.30595160e-02f, - -2.24288797e-02f, -2.17956350e-02f, -2.11598719e-02f, -2.05215604e-02f, -1.98808758e-02f, -1.92378572e-02f, - -1.85926285e-02f, -1.79452959e-02f, -1.72958111e-02f, -1.66443892e-02f, -1.59910910e-02f, -1.53360054e-02f, - -1.46791138e-02f, -1.40206370e-02f, -1.33606051e-02f, -1.26990922e-02f, -1.20361993e-02f, -1.13720243e-02f, - -1.07066151e-02f, -1.00401429e-02f, -9.37251228e-03f, -8.70406051e-03f, -8.03464801e-03f, -7.36450108e-03f, - -6.69365739e-03f, -6.02224331e-03f, -5.35026177e-03f, -4.67784908e-03f, -4.00512451e-03f, -3.33208341e-03f, - -2.65891961e-03f, -1.98567946e-03f, -1.31241451e-03f, -6.39242061e-04f, 3.37369380e-05f, 7.06495602e-04f, - 1.37885314e-03f, 2.05079501e-03f, 2.72222342e-03f, 3.39306398e-03f, 4.06316754e-03f, 4.73252479e-03f, - 5.40098673e-03f, 6.06850097e-03f, 6.73499535e-03f, 7.40037038e-03f, 8.06453546e-03f, 8.72739520e-03f, - 9.38888459e-03f, 1.00488890e-02f, 1.07073334e-02f, 1.13642016e-02f, 1.20193145e-02f, 1.26726593e-02f, - 1.33241068e-02f, 1.39735765e-02f, 1.46209857e-02f, 1.52662938e-02f, 1.59093518e-02f, 1.65501618e-02f, - 1.71885306e-02f, 1.78244863e-02f, 1.84579043e-02f, 1.90887015e-02f, 1.97167718e-02f, 2.03420511e-02f, - 2.09644896e-02f, 2.15839620e-02f, 2.22004501e-02f, 2.28138312e-02f, 2.34240688e-02f, 2.40309818e-02f, - 2.46346218e-02f, 2.52348320e-02f, 2.58315460e-02f, 2.64247199e-02f, 2.70142581e-02f, 2.76001192e-02f, - 2.81821218e-02f, 2.87603322e-02f, 2.93346028e-02f, 2.99048520e-02f, 3.04710341e-02f, 3.10330849e-02f, - 3.15909011e-02f, 3.21444365e-02f, 3.26936176e-02f, 3.32383669e-02f, 3.37786170e-02f, 3.43143333e-02f, - 3.48454266e-02f, 3.53717817e-02f, 3.58933801e-02f, 3.64101966e-02f, 3.69220327e-02f, 3.74289640e-02f, - 3.79309059e-02f, 3.84277234e-02f, 3.89194106e-02f, 3.94058653e-02f, 3.98870696e-02f, 4.03629591e-02f, - 4.08334781e-02f, 4.12984741e-02f, 4.17580325e-02f, 4.22120136e-02f, 4.26603813e-02f, 4.31030318e-02f, - 4.35400190e-02f, 4.39711801e-02f, 4.43964967e-02f, 4.48159942e-02f, 4.52294168e-02f, 4.56370135e-02f, - 4.60384453e-02f, 4.64338525e-02f, 4.68230471e-02f, 4.72060900e-02f, 4.75829400e-02f, 4.79534552e-02f, - 4.83176720e-02f, 4.86754813e-02f, 4.90268953e-02f, 4.93718364e-02f, 4.97102976e-02f, 5.00421942e-02f, - 5.03675532e-02f, 5.06862115e-02f, 5.09982473e-02f, 5.13036286e-02f, 5.16022039e-02f, 5.18940569e-02f, - 5.21791019e-02f, 5.24572284e-02f, 5.27285485e-02f, 5.29929239e-02f, 5.32504167e-02f, 5.35009335e-02f, - 5.37443851e-02f, 5.39808632e-02f, 5.42102459e-02f, 5.44325584e-02f, 5.46477938e-02f, 5.48558486e-02f, - 5.50568213e-02f, 5.52505047e-02f, 5.54370646e-02f, 5.56163441e-02f, 5.57884039e-02f, 5.59532332e-02f, - 5.61107236e-02f, 5.62608923e-02f, 5.64037951e-02f, 5.65393598e-02f, 5.66675619e-02f, 5.67883951e-02f, - 5.69018444e-02f, 5.70079554e-02f, 5.71065606e-02f, 5.71978746e-02f, 5.72816793e-02f, 5.73581687e-02f, - 5.74270993e-02f, 5.74886492e-02f, 5.75427616e-02f, 5.75893886e-02f, 5.76286308e-02f, 5.76603254e-02f, - 5.76846449e-02f, 5.77014257e-02f, 5.77108614e-02f, 5.77127311e-02f, 5.77072272e-02f, 5.76942492e-02f, - 5.76738085e-02f, 5.76459431e-02f, 5.76106272e-02f, 5.75679353e-02f, 5.75177952e-02f, 5.74602296e-02f, - 5.73952688e-02f, 5.73229578e-02f, 5.72432241e-02f, 5.71561710e-02f, 5.70617459e-02f, 5.69600127e-02f, - 5.68509542e-02f, 5.67345715e-02f, 5.66109051e-02f, 5.64799898e-02f, 5.63418300e-02f, 5.61964419e-02f, - 5.60438796e-02f, 5.58841158e-02f, 5.57171405e-02f, 5.55431499e-02f, 5.53619909e-02f, 5.51737063e-02f, - 5.49784279e-02f, 5.47760786e-02f, 5.45667696e-02f, 5.43504474e-02f, 5.41272489e-02f, 5.38971056e-02f, - 5.36600845e-02f, 5.34162300e-02f, 5.31655860e-02f, 5.29081226e-02f, 5.26439939e-02f, 5.23730855e-02f, - 5.20955637e-02f, 5.18114074e-02f, 5.15206573e-02f, 5.12233723e-02f, 5.09195766e-02f, 5.06092934e-02f, - 5.02926138e-02f, 4.99696089e-02f, 4.96402025e-02f, 4.93045124e-02f, 4.89625888e-02f, 4.86144944e-02f, - 4.82602267e-02f, 4.78998585e-02f, 4.75334117e-02f, 4.71610399e-02f, 4.67826349e-02f, 4.63983641e-02f, - 4.60082515e-02f, 4.56123157e-02f, 4.52106481e-02f, 4.48033218e-02f, 4.43903075e-02f, 4.39717655e-02f, - 4.35476423e-02f, 4.31181046e-02f, 4.26831386e-02f, 4.22428100e-02f, 4.17972030e-02f, 4.13463534e-02f, - 4.08903603e-02f, 4.04292004e-02f, 3.99630382e-02f, 3.94918619e-02f, 3.90157944e-02f, 3.85348356e-02f, - 3.80490896e-02f, 3.75586089e-02f, 3.70634426e-02f, 3.65637255e-02f, 3.60594008e-02f, 3.55506404e-02f, - 3.50374752e-02f, 3.45199702e-02f, 3.39982161e-02f, 3.34722387e-02f, 3.29422246e-02f, 3.24080216e-02f, - 3.18699149e-02f, 3.13278339e-02f, 3.07819765e-02f, 3.02323013e-02f, 2.96789493e-02f, 2.91219574e-02f, - 2.85613904e-02f, 2.79974132e-02f, 2.74299673e-02f, 2.68591915e-02f, 2.62851888e-02f, 2.57079993e-02f, - 2.51276953e-02f, 2.45443535e-02f, 2.39580739e-02f, 2.33689311e-02f, 2.27769653e-02f, 2.21823066e-02f, - 2.15849810e-02f, 2.09850925e-02f, 2.03827760e-02f, 1.97779116e-02f, 1.91708556e-02f, 1.85614915e-02f, - 1.79500127e-02f, 1.73363802e-02f, 1.67207342e-02f, 1.61031868e-02f, 1.54838038e-02f, 1.48626447e-02f, - 1.42397744e-02f, 1.36153172e-02f, 1.29893733e-02f, 1.23619535e-02f, 1.17331483e-02f, 1.11031063e-02f, - 1.04718091e-02f, 9.83948570e-03f, 9.20604392e-03f, 8.57170867e-03f, 7.93644080e-03f, 7.30045552e-03f, - 6.66372169e-03f, 6.02642675e-03f, 5.38852469e-03f, 4.75022399e-03f, 4.11149347e-03f, 3.47256149e-03f, - 2.83332932e-03f, 2.19399443e-03f, 1.55465433e-03f, 9.15301625e-04f, 2.76123541e-04f, -3.62868278e-04f, - -1.00156418e-03f, -1.63988491e-03f, -2.27776635e-03f, -2.91511927e-03f, -3.55180377e-03f, -4.18782811e-03f, - -4.82310433e-03f, -5.45744890e-03f, -6.09088213e-03f, -6.72325090e-03f, -7.35454097e-03f, -7.98468263e-03f, - -8.61348015e-03f, -9.24091439e-03f, -9.86696472e-03f, -1.04914970e-02f, -1.11144404e-02f, -1.17356979e-02f, - -1.23551680e-02f, -1.29728720e-02f, -1.35885701e-02f, -1.42023842e-02f, -1.48140426e-02f, -1.54236074e-02f, - -1.60308971e-02f, -1.66358902e-02f, -1.72385727e-02f, -1.78387170e-02f, -1.84363508e-02f, -1.90313644e-02f, - -1.96236897e-02f, -2.02132605e-02f, -2.07999738e-02f, -2.13838061e-02f, -2.19646220e-02f, -2.25423640e-02f, - -2.31170306e-02f, -2.36883907e-02f, -2.42565682e-02f, -2.48213275e-02f, -2.53826556e-02f, -2.59405298e-02f, - -2.64947848e-02f, -2.70454606e-02f, -2.75923749e-02f, -2.81355220e-02f, -2.86748476e-02f, -2.92101990e-02f, - -2.97416339e-02f, -3.02689828e-02f, -3.07922050e-02f, -3.13112602e-02f, -3.18260409e-02f, -3.23365466e-02f, - -3.28426132e-02f, -3.33443148e-02f, -3.38414341e-02f, -3.43340285e-02f, -3.48219936e-02f, -3.53052568e-02f, - -3.57837446e-02f, -3.62573982e-02f, -3.67262814e-02f, -3.71900977e-02f, -3.76490199e-02f, -3.81028417e-02f, - -3.85515661e-02f, -3.89951393e-02f, -3.94335093e-02f, -3.98665951e-02f, -4.02943654e-02f, -4.07167178e-02f, - -4.11336619e-02f, -4.15451228e-02f, -4.19510466e-02f, -4.23513965e-02f, -4.27460399e-02f, -4.31351039e-02f, - -4.35183535e-02f, -4.38958472e-02f, -4.42675346e-02f, -4.46333161e-02f, -4.49932038e-02f, -4.53471345e-02f, - -4.56949890e-02f, -4.60368850e-02f, -4.63726407e-02f, -4.67022617e-02f, -4.70257051e-02f, -4.73429343e-02f, - -4.76539681e-02f, -4.79586289e-02f, -4.82569864e-02f, -4.85489783e-02f, -4.88346231e-02f, -4.91137961e-02f, - -4.93864961e-02f, -4.96527038e-02f, -4.99123459e-02f, -5.01654516e-02f, -5.04119580e-02f, -5.06518474e-02f, - -5.08850715e-02f, -5.11116404e-02f, -5.13314688e-02f, -5.15445902e-02f, -5.17509177e-02f, -5.19505193e-02f, - -5.21432626e-02f, -5.23291877e-02f, -5.25082527e-02f, -5.26804586e-02f, -5.28458246e-02f, -5.30041863e-02f, - -5.31556932e-02f, -5.33001892e-02f, -5.34378137e-02f, -5.35683871e-02f, -5.36919870e-02f, -5.38085820e-02f, - -5.39181757e-02f, -5.40207443e-02f, -5.41162347e-02f, -5.42047043e-02f, -5.42860963e-02f, -5.43604661e-02f, - -5.44277540e-02f, -5.44878952e-02f, -5.45410136e-02f, -5.45870202e-02f, -5.46259645e-02f, -5.46577975e-02f, - -5.46825183e-02f, -5.47001225e-02f, -5.47106786e-02f, -5.47141436e-02f, -5.47104985e-02f, -5.46997305e-02f, - -5.46818859e-02f, -5.46569952e-02f, -5.46250235e-02f, -5.45859848e-02f, -5.45398696e-02f, -5.44867086e-02f, - -5.44264634e-02f, -5.43592373e-02f, -5.42849790e-02f, -5.42037119e-02f, -5.41154169e-02f, -5.40201870e-02f, - -5.39179424e-02f, -5.38088068e-02f, -5.36926647e-02f, -5.35697012e-02f, -5.34397449e-02f, -5.33029696e-02f, - -5.31592653e-02f, -5.30087691e-02f, -5.28514673e-02f, -5.26873604e-02f, -5.25164963e-02f, -5.23388757e-02f, - -5.21545414e-02f, -5.19634586e-02f, -5.17658322e-02f, -5.15614235e-02f, -5.13504965e-02f, -5.11330103e-02f, - -5.09089092e-02f, -5.06782845e-02f, -5.04412293e-02f, -5.01977249e-02f, -4.99477902e-02f, -4.96914368e-02f, - -4.94287522e-02f, -4.91597415e-02f, -4.88845281e-02f, -4.86030154e-02f, -4.83153533e-02f, -4.80214466e-02f, - -4.77214928e-02f, -4.74154676e-02f, -4.71033619e-02f, -4.67853200e-02f, -4.64612942e-02f, -4.61313604e-02f, - -4.57955714e-02f, -4.54539690e-02f, -4.51066413e-02f, -4.47535448e-02f, -4.43947976e-02f, -4.40303977e-02f, - -4.36604634e-02f, -4.32849919e-02f, -4.29040452e-02f, -4.25176539e-02f, -4.21259449e-02f, -4.17288306e-02f, - -4.13265644e-02f, -4.09190266e-02f, -4.05063328e-02f, -4.00885517e-02f, -3.96657296e-02f, -3.92379173e-02f, - -3.88051455e-02f, -3.83675489e-02f, -3.79251196e-02f, -3.74779367e-02f, -3.70260758e-02f, -3.65695612e-02f, - -3.61084834e-02f, -3.56429127e-02f, -3.51728235e-02f, -3.46984283e-02f, -3.42196306e-02f, -3.37366551e-02f, - -3.32494651e-02f, -3.27581050e-02f, -3.22627399e-02f, -3.17632937e-02f, -3.12599673e-02f, -3.07527759e-02f, - -3.02417767e-02f, -2.97270587e-02f, -2.92086106e-02f, -2.86866463e-02f, -2.81610919e-02f, -2.76321392e-02f, - -2.70998282e-02f, -2.65641042e-02f, -2.60251777e-02f, -2.54830941e-02f, -2.49378993e-02f, -2.43896378e-02f, - -2.38384745e-02f, -2.32843518e-02f, -2.27275087e-02f, -2.21678571e-02f, -2.16055646e-02f, -2.10406553e-02f, - -2.04732583e-02f, -1.99034385e-02f, -1.93311898e-02f, -1.87566867e-02f, -1.81799389e-02f, -1.76010735e-02f, - -1.70201182e-02f, -1.64371907e-02f, -1.58523579e-02f, -1.52656265e-02f, -1.46772249e-02f, -1.40870679e-02f, - -1.34953827e-02f, -1.29020814e-02f, -1.23073559e-02f, -1.17112799e-02f, -1.11138968e-02f, -1.05153071e-02f, - -9.91553633e-03f, -9.31473643e-03f, -8.71295357e-03f, -8.11025382e-03f, -7.50674477e-03f, -6.90247140e-03f, - -6.29751807e-03f, -5.69201683e-03f, -5.08597066e-03f, -4.47952693e-03f, -3.87265710e-03f, -3.26559343e-03f, - -2.65830151e-03f, -2.05088272e-03f, -1.44344203e-03f, -8.36020644e-04f, -2.28761174e-04f, 3.78356283e-04f, - 9.85139106e-04f, 1.59159320e-03f, 2.19762576e-03f, 2.80311048e-03f, 3.40803096e-03f, 4.01226921e-03f, - 4.61577304e-03f, 5.21841537e-03f, 5.82022152e-03f, 6.42097102e-03f, 7.02070625e-03f, 7.61928101e-03f, - 8.21664385e-03f, 8.81277573e-03f, 9.40742761e-03f, 1.00006961e-02f, 1.05924094e-02f, 1.11825813e-02f, - 1.17710567e-02f, 1.23577493e-02f, 1.29426535e-02f, 1.35256408e-02f, 1.41066555e-02f, 1.46856230e-02f, - 1.52624621e-02f, 1.58371120e-02f, 1.64094483e-02f, 1.69794774e-02f, 1.75470797e-02f, 1.81121825e-02f, - 1.86747195e-02f, 1.92346079e-02f, 1.97918116e-02f, 2.03461889e-02f, 2.08977751e-02f, 2.14464351e-02f, - 2.19920832e-02f, 2.25346633e-02f, 2.30741262e-02f, 2.36103758e-02f, 2.41433138e-02f, 2.46729685e-02f, - 2.51991888e-02f, 2.57219697e-02f, 2.62412616e-02f, 2.67568276e-02f, 2.72687699e-02f, 2.77770207e-02f, - 2.82814519e-02f, 2.87819568e-02f, 2.92786031e-02f, 2.97712517e-02f, 3.02598379e-02f, 3.07443121e-02f, - 3.12245557e-02f, 3.17006096e-02f, 3.21724151e-02f, 3.26397551e-02f, 3.31027673e-02f, 3.35612615e-02f, - 3.40152128e-02f, 3.44646181e-02f, 3.49092877e-02f, 3.53493587e-02f, 3.57845978e-02f, 3.62150682e-02f, - 3.66406634e-02f, 3.70613306e-02f, 3.74769623e-02f, 3.78876533e-02f, 3.82932248e-02f, 3.86936670e-02f, - 3.90889650e-02f, 3.94789988e-02f, 3.98637753e-02f, 4.02431743e-02f, 4.06172531e-02f, 4.09859008e-02f, - 4.13491249e-02f, 4.17067395e-02f, 4.20588701e-02f, 4.24053324e-02f, 4.27462878e-02f, 4.30814274e-02f, - 4.34108826e-02f, 4.37346003e-02f, 4.40524545e-02f, 4.43645265e-02f, 4.46706544e-02f, 4.49708939e-02f, - 4.52651365e-02f, 4.55534552e-02f, 4.58356998e-02f, 4.61118787e-02f, 4.63819790e-02f, 4.66459456e-02f, - 4.69036725e-02f, 4.71552776e-02f, 4.74006627e-02f, 4.76397936e-02f, 4.78725986e-02f, 4.80991269e-02f, - 4.83192853e-02f, 4.85331342e-02f, 4.87405487e-02f, 4.89415479e-02f, 4.91361168e-02f, 4.93242184e-02f, - 4.95058522e-02f, 4.96809339e-02f, 4.98495835e-02f, 5.00115778e-02f, 5.01670957e-02f, 5.03159582e-02f, - 5.04582671e-02f, 5.05939539e-02f, 5.07230239e-02f, 5.08454137e-02f, 5.09611711e-02f, 5.10702458e-02f, - 5.11726416e-02f, 5.12683420e-02f, 5.13573625e-02f, 5.14396517e-02f, 5.15152056e-02f, 5.15840627e-02f, - 5.16461326e-02f, 5.17015374e-02f, 5.17501012e-02f, 5.17920261e-02f, 5.18270966e-02f, 5.18555006e-02f, - 5.18770872e-02f, 5.18919209e-02f, 5.19000583e-02f, 5.19013666e-02f, 5.18959635e-02f, 5.18838034e-02f, - 5.18649079e-02f, 5.18392968e-02f, 5.18069106e-02f, 5.17677835e-02f, 5.17219693e-02f, 5.16694272e-02f, - 5.16102054e-02f, 5.15442541e-02f, 5.14716839e-02f, 5.13923839e-02f, 5.13064596e-02f, 5.12138838e-02f, - 5.11146855e-02f, 5.10088576e-02f, 5.08964708e-02f, 5.07774953e-02f, 5.06519384e-02f, 5.05198072e-02f, - 5.03811981e-02f, 5.02360723e-02f, 5.00844687e-02f, 4.99264100e-02f, 4.97618956e-02f, 4.95909864e-02f, - 4.94137208e-02f, 4.92300147e-02f, 4.90400518e-02f, 4.88436987e-02f, 4.86411687e-02f, 4.84322719e-02f, - 4.82172094e-02f, 4.79959299e-02f, 4.77685303e-02f, 4.75349530e-02f, 4.72952893e-02f, 4.70495982e-02f, - 4.67977949e-02f, 4.65400971e-02f, 4.62763778e-02f, 4.60067415e-02f, 4.57312504e-02f, 4.54498806e-02f, - 4.51626894e-02f, 4.48697407e-02f, 4.45710589e-02f, 4.42667227e-02f, 4.39566803e-02f, 4.36410849e-02f, - 4.33198886e-02f, 4.29932320e-02f, 4.26610439e-02f, 4.23234559e-02f, 4.19804474e-02f, 4.16321967e-02f, - 4.12785716e-02f, 4.09197058e-02f, 4.05556850e-02f, 4.01865064e-02f, 3.98122378e-02f, 3.94329165e-02f, - 3.90486191e-02f, 3.86593650e-02f, 3.82652711e-02f, 3.78663265e-02f, 3.74625220e-02f, 3.70541289e-02f, - 3.66409309e-02f, 3.62232247e-02f, 3.58008872e-02f, 3.53740911e-02f, 3.49428350e-02f, 3.45071465e-02f, - 3.40672274e-02f, 3.36229364e-02f, 3.31745064e-02f, 3.27219003e-02f, 3.22652186e-02f, 3.18044682e-02f, - 3.13397873e-02f, 3.08711530e-02f, 3.03987388e-02f, 2.99224968e-02f, 2.94425653e-02f, 2.89589626e-02f, - 2.84717772e-02f, 2.79810831e-02f, 2.74868955e-02f, 2.69893435e-02f, 2.64884201e-02f, 2.59842903e-02f, - 2.54769255e-02f, 2.49664582e-02f, 2.44529334e-02f, 2.39363949e-02f, 2.34169622e-02f, 2.28946206e-02f, - 2.23695514e-02f, 2.18417176e-02f, 2.13113019e-02f, 2.07782459e-02f, 2.02427031e-02f, 1.97047663e-02f, - 1.91644034e-02f, 1.86217777e-02f, 1.80769281e-02f, 1.75298818e-02f, 1.69808735e-02f, 1.64297236e-02f, - 1.58767497e-02f, 1.53218350e-02f, 1.47651550e-02f, 1.42068238e-02f, 1.36467878e-02f, 1.30851844e-02f, - 1.25220994e-02f, 1.19575723e-02f, 1.13917229e-02f, 1.08246191e-02f, 1.02562973e-02f, 9.68684158e-03f, - 9.11637831e-03f, 8.54488961e-03f, 7.97253044e-03f, 7.39931952e-03f, 6.82540141e-03f, 6.25076157e-03f, - 5.67558142e-03f, 5.09982386e-03f, 4.52364424e-03f, 3.94711655e-03f, 3.37022433e-03f, 2.79318408e-03f, - 2.21591799e-03f, 1.63865246e-03f, 1.06135518e-03f, 4.84125511e-04f, -9.29591003e-05f, -6.69772273e-04f, - -1.24635635e-03f, -1.82243743e-03f, -2.39816018e-03f, -2.97334105e-03f, -3.54790317e-03f, -4.12180736e-03f, - -4.69494428e-03f, -5.26724104e-03f, -5.83865553e-03f, -6.40911434e-03f, -6.97847120e-03f, -7.54675294e-03f, - -8.11383992e-03f, -8.67962505e-03f, -9.24410653e-03f, -9.80710241e-03f, -1.03686834e-02f, -1.09286839e-02f, - -1.14870258e-02f, -1.20436573e-02f, -1.25985535e-02f, -1.31515877e-02f, -1.37026830e-02f, -1.42517791e-02f, - -1.47988319e-02f, -1.53437493e-02f, -1.58864710e-02f, -1.64268722e-02f, -1.69649988e-02f, -1.75006326e-02f, - -1.80338645e-02f, -1.85645089e-02f, -1.90925017e-02f, -1.96178647e-02f, -2.01404667e-02f, -2.06602607e-02f, - -2.11771045e-02f, -2.16909978e-02f, -2.22019569e-02f, -2.27097600e-02f, -2.32144315e-02f, -2.37158569e-02f, - -2.42140964e-02f, -2.47088952e-02f, -2.52002975e-02f, -2.56882612e-02f, -2.61726736e-02f, -2.66535547e-02f, - -2.71307303e-02f, -2.76041878e-02f, -2.80738507e-02f, -2.85396892e-02f, -2.90016779e-02f, -2.94596512e-02f, - -2.99136442e-02f, -3.03635523e-02f, -3.08093855e-02f, -3.12509674e-02f, -3.16883341e-02f, -3.21214133e-02f, - -3.25501486e-02f, -3.29744444e-02f, -3.33942895e-02f, -3.38096520e-02f, -3.42204542e-02f, -3.46266279e-02f, - -3.50280969e-02f, -3.54248920e-02f, -3.58168991e-02f, -3.62041226e-02f, -3.65864337e-02f, -3.69638830e-02f, - -3.73362970e-02f, -3.77037818e-02f, -3.80661651e-02f, -3.84234578e-02f, -3.87756003e-02f, -3.91225874e-02f, - -3.94643206e-02f, -3.98007370e-02f, -4.01319003e-02f, -4.04576773e-02f, -4.07780577e-02f, -4.10930309e-02f, - -4.14024812e-02f, -4.17064496e-02f, -4.20048228e-02f, -4.22976562e-02f, -4.25848313e-02f, -4.28663655e-02f, - -4.31421834e-02f, -4.34122692e-02f, -4.36765782e-02f, -4.39351462e-02f, -4.41878452e-02f, -4.44347362e-02f, - -4.46756667e-02f, -4.49106961e-02f, -4.51397975e-02f, -4.53629726e-02f, -4.55800893e-02f, -4.57911479e-02f, - -4.59962035e-02f, -4.61951884e-02f, -4.63880532e-02f, -4.65747561e-02f, -4.67554301e-02f, -4.69298158e-02f, - -4.70980970e-02f, -4.72600764e-02f, -4.74159367e-02f, -4.75654586e-02f, -4.77088186e-02f, -4.78458303e-02f, - -4.79765623e-02f, -4.81010306e-02f, -4.82191056e-02f, -4.83308643e-02f, -4.84362784e-02f, -4.85353460e-02f, - -4.86280642e-02f, -4.87143870e-02f, -4.87942814e-02f, -4.88678313e-02f, -4.89349678e-02f, -4.89956572e-02f, - -4.90499778e-02f, -4.90978512e-02f, -4.91393393e-02f, -4.91743344e-02f, -4.92029749e-02f, -4.92250856e-02f, - -4.92408667e-02f, -4.92501523e-02f, -4.92530412e-02f, -4.92495040e-02f, -4.92394956e-02f, -4.92231529e-02f, - -4.92002827e-02f, -4.91710624e-02f, -4.91354301e-02f, -4.90934195e-02f, -4.90449724e-02f, -4.89901563e-02f, - -4.89289974e-02f, -4.88614910e-02f, -4.87875263e-02f, -4.87073256e-02f, -4.86207399e-02f, -4.85279368e-02f, - -4.84287037e-02f, -4.83232730e-02f, -4.82115368e-02f, -4.80935715e-02f, -4.79694003e-02f, -4.78389342e-02f, - -4.77023252e-02f, -4.75595638e-02f, -4.74105782e-02f, -4.72555083e-02f, -4.70942991e-02f, -4.69270751e-02f, - -4.67537172e-02f, -4.65743618e-02f, -4.63889178e-02f, -4.61975875e-02f, -4.60002379e-02f, -4.57969808e-02f, - -4.55878200e-02f, -4.53727660e-02f, -4.51518770e-02f, -4.49252189e-02f, -4.46927100e-02f, -4.44545059e-02f, - -4.42105880e-02f, -4.39609555e-02f, -4.37057026e-02f, -4.34448041e-02f, -4.31783680e-02f, -4.29063840e-02f, - -4.26289382e-02f, -4.23459497e-02f, -4.20576067e-02f, -4.17638416e-02f, -4.14647321e-02f, -4.11603608e-02f, - -4.08506937e-02f, -4.05358435e-02f, -4.02157750e-02f, -3.98905871e-02f, -3.95603342e-02f, -3.92250054e-02f, - -3.88847265e-02f, -3.85394883e-02f, -3.81893052e-02f, -3.78342670e-02f, -3.74744642e-02f, -3.71098676e-02f, - -3.67406014e-02f, -3.63666676e-02f, -3.59880727e-02f, -3.56049946e-02f, -3.52173400e-02f, -3.48252717e-02f, - -3.44287810e-02f, -3.40279719e-02f, -3.36228564e-02f, -3.32134862e-02f, -3.27999416e-02f, -3.23822642e-02f, - -3.19604989e-02f, -3.15347955e-02f, -3.11050287e-02f, -3.06714393e-02f, -3.02339337e-02f, -2.97927138e-02f, - -2.93476999e-02f, -2.88991079e-02f, -2.84468413e-02f, -2.79910279e-02f, -2.75317378e-02f, -2.70690468e-02f, - -2.66029561e-02f, -2.61336268e-02f, -2.56609916e-02f, -2.51851972e-02f, -2.47062887e-02f, -2.42243765e-02f, - -2.37394712e-02f, -2.32516181e-02f, -2.27608617e-02f, -2.22673829e-02f, -2.17711948e-02f, -2.12723246e-02f, - -2.07708587e-02f, -2.02668472e-02f, -1.97603953e-02f, -1.92515712e-02f, -1.87403807e-02f, -1.82269633e-02f, - -1.77113569e-02f, -1.71936045e-02f, -1.66738428e-02f, -1.61520138e-02f, -1.56283933e-02f, -1.51028020e-02f, - -1.45755367e-02f, -1.40465159e-02f, -1.35158418e-02f, -1.29836413e-02f, -1.24499104e-02f, -1.19147714e-02f, - -1.13782306e-02f, -1.08404929e-02f, -1.03014799e-02f, -9.76129446e-03f, -9.22008183e-03f, -8.67786956e-03f, - -8.13473766e-03f, -7.59072613e-03f, -7.04588425e-03f, -6.50035890e-03f, -5.95419773e-03f, -5.40746802e-03f, - -4.86023207e-03f, -4.31251169e-03f, -3.76452631e-03f, -3.21619679e-03f, -2.66768596e-03f, -2.11895782e-03f, - -1.57024665e-03f, -1.02150119e-03f, -4.72799407e-04f, 7.56999494e-05f, 6.24079678e-04f, 1.17206600e-03f, - 1.71974689e-03f, 2.26700490e-03f, 2.81372126e-03f, 3.35995233e-03f, 3.90544842e-03f, 4.45026326e-03f, - 4.99427066e-03f, 5.53747809e-03f, 6.07972557e-03f, 6.62093401e-03f, 7.16116843e-03f, 7.70017412e-03f, - 8.23801341e-03f, 8.77455450e-03f, 9.30979829e-03f, 9.84360193e-03f, 1.03758652e-02f, 1.09066437e-02f, - 1.14357725e-02f, 1.19632323e-02f, 1.24888520e-02f, 1.30127237e-02f, 1.35346823e-02f, 1.40546609e-02f, - 1.45725958e-02f, 1.50884521e-02f, 1.56021449e-02f, 1.61136094e-02f, 1.66227704e-02f, 1.71295622e-02f, - 1.76339198e-02f, 1.81358043e-02f, 1.86350993e-02f, 1.91317969e-02f, 1.96258190e-02f, 2.01170551e-02f, - 2.06055263e-02f, 2.10910635e-02f, 2.15736779e-02f, 2.20533416e-02f, 2.25298456e-02f, 2.30033247e-02f, - 2.34735389e-02f, 2.39405808e-02f, 2.44042607e-02f, 2.48646366e-02f, 2.53215335e-02f, 2.57749516e-02f, - 2.62248415e-02f, 2.66711599e-02f, 2.71138174e-02f, 2.75527225e-02f, 2.79878554e-02f, 2.84192308e-02f, - 2.88466811e-02f, 2.92702253e-02f, 2.96897905e-02f, 3.01053042e-02f, 3.05166636e-02f, 3.09239425e-02f, - 3.13270779e-02f, 3.17258825e-02f, 3.21204174e-02f, 3.25105532e-02f, 3.28963561e-02f, 3.32776995e-02f, - 3.36545309e-02f, 3.40268394e-02f, 3.43945652e-02f, 3.47576355e-02f, 3.51160146e-02f, 3.54696975e-02f, - 3.58185811e-02f, 3.61626468e-02f, 3.65019172e-02f, 3.68362085e-02f, 3.71655925e-02f, 3.74899853e-02f, - 3.78093602e-02f, 3.81236539e-02f, 3.84328431e-02f, 3.87369092e-02f, 3.90358112e-02f, 3.93294570e-02f, - 3.96178717e-02f, 3.99010179e-02f, 4.01787562e-02f, 4.04511852e-02f, 4.07182428e-02f, 4.09798590e-02f, - 4.12360165e-02f, 4.14866682e-02f, 4.17318117e-02f, 4.19713799e-02f, 4.22054268e-02f, 4.24338273e-02f, - 4.26565807e-02f, 4.28736975e-02f, 4.30851150e-02f, 4.32907833e-02f, 4.34907422e-02f, 4.36849613e-02f, - 4.38733682e-02f, 4.40559461e-02f, 4.42327057e-02f, 4.44036333e-02f, 4.45686549e-02f, 4.47278248e-02f, - 4.48810178e-02f, 4.50283297e-02f, 4.51696758e-02f, 4.53050892e-02f, 4.54344938e-02f, 4.55579235e-02f, - 4.56753356e-02f, 4.57867255e-02f, 4.58920951e-02f, 4.59914026e-02f, 4.60846229e-02f, 4.61718755e-02f, - 4.62529547e-02f, 4.63280851e-02f, 4.63969458e-02f, 4.64598393e-02f, 4.65165784e-02f, 4.65672137e-02f, - 4.66117738e-02f, 4.66501536e-02f, 4.66824580e-02f, 4.67085893e-02f, 4.67286950e-02f, 4.67426048e-02f, - 4.67504078e-02f, 4.67520930e-02f, 4.67476408e-02f, 4.67371131e-02f, 4.67204641e-02f, 4.66976231e-02f, - 4.66688139e-02f, 4.66338384e-02f, 4.65927571e-02f, 4.65455952e-02f, 4.64923952e-02f, 4.64331075e-02f, - 4.63677813e-02f, 4.62963885e-02f, 4.62189479e-02f, 4.61355213e-02f, 4.60461070e-02f, 4.59506466e-02f, - 4.58492227e-02f, 4.57418457e-02f, 4.56285245e-02f, 4.55092698e-02f, 4.53840803e-02f, 4.52530405e-02f, - 4.51160935e-02f, 4.49733102e-02f, 4.48246703e-02f, 4.46702076e-02f, 4.45100127e-02f, 4.43439813e-02f, - 4.41722716e-02f, 4.39948210e-02f, 4.38116605e-02f, 4.36228683e-02f, 4.34283966e-02f, 4.32283356e-02f, - 4.30226269e-02f, 4.28114689e-02f, 4.25947456e-02f, 4.23724794e-02f, 4.21448078e-02f, 4.19116663e-02f, - 4.16731434e-02f, 4.14292580e-02f, 4.11800016e-02f, 4.09254775e-02f, 4.06657605e-02f, 4.04007045e-02f, - 4.01304894e-02f, 3.98551387e-02f, 3.95746384e-02f, 3.92891195e-02f, 3.89985348e-02f, 3.87029196e-02f, - 3.84023727e-02f, 3.80969199e-02f, 3.77865799e-02f, 3.74714449e-02f, 3.71514773e-02f, 3.68267902e-02f, - 3.64973702e-02f, 3.61633364e-02f, 3.58246285e-02f, 3.54814560e-02f, 3.51336475e-02f, 3.47814476e-02f, - 3.44248157e-02f, 3.40637624e-02f, 3.36984543e-02f, 3.33288257e-02f, 3.29549912e-02f, 3.25769615e-02f, - 3.21948294e-02f, 3.18085729e-02f, 3.14183492e-02f, 3.10241265e-02f, 3.06260339e-02f, 3.02240140e-02f, - 2.98182222e-02f, 2.94086750e-02f, 2.89954048e-02f, 2.85785530e-02f, 2.81580438e-02f, 2.77340469e-02f, - 2.73065457e-02f, 2.68757013e-02f, 2.64413820e-02f, 2.60038347e-02f, 2.55630460e-02f, 2.51190535e-02f, - 2.46719615e-02f, 2.42217682e-02f, 2.37685815e-02f, 2.33124504e-02f, 2.28534680e-02f, 2.23916292e-02f, - 2.19270361e-02f, 2.14597725e-02f, 2.09898064e-02f, 2.05173714e-02f, 2.00423104e-02f, 1.95648858e-02f, - 1.90850142e-02f, 1.86029045e-02f, 1.81184385e-02f, 1.76318575e-02f, 1.71431298e-02f, 1.66523018e-02f, - 1.61595299e-02f, 1.56647176e-02f, 1.51682242e-02f, 1.46697557e-02f, 1.41696498e-02f, 1.36678591e-02f, - 1.31644259e-02f, 1.26594738e-02f, 1.21530675e-02f, 1.16452747e-02f, 1.11360981e-02f, 1.06256870e-02f, - 1.01140811e-02f, 9.60129948e-03f, 9.08748776e-03f, 8.57266461e-03f, 8.05691163e-03f, 7.54028166e-03f, - 7.02289416e-03f, 6.50474865e-03f, 5.98598021e-03f, 5.46653372e-03f, 4.94669967e-03f, 4.42628100e-03f, - 3.90561108e-03f, 3.38447759e-03f, 2.86316392e-03f, 2.34168357e-03f, 1.82012529e-03f, 1.29846264e-03f, - 7.76851777e-04f, 2.55292091e-04f, -2.66110888e-04f, -7.87210640e-04f, -1.30802647e-03f, -1.82852121e-03f, - -2.34855263e-03f, -2.86809928e-03f, -3.38703581e-03f, -3.90536227e-03f, -4.42298779e-03f, -4.93983583e-03f, - -5.45588180e-03f, -5.97093662e-03f, -6.48509083e-03f, -6.99813221e-03f, -7.51013797e-03f, -8.02091634e-03f, - -8.53048539e-03f, -9.03873794e-03f, -9.54557623e-03f, -1.00510253e-02f, -1.05549308e-02f, -1.10572931e-02f, - -1.15580273e-02f, -1.20570208e-02f, -1.25542477e-02f, -1.30496899e-02f, -1.35431569e-02f, -1.40347360e-02f, - -1.45243010e-02f, -1.50117345e-02f, -1.54970591e-02f, -1.59800604e-02f, -1.64608989e-02f, -1.69393503e-02f, - -1.74154671e-02f, -1.78890533e-02f, -1.83601637e-02f, -1.88286315e-02f, -1.92944687e-02f, -1.97576594e-02f, - -2.02180505e-02f, -2.06756186e-02f, -2.11303180e-02f, -2.15820430e-02f, -2.20307865e-02f, -2.24764836e-02f, - -2.29190707e-02f, -2.33584579e-02f, -2.37946594e-02f, -2.42275373e-02f, -2.46571184e-02f, -2.50832883e-02f, - -2.55059764e-02f, -2.59252218e-02f, -2.63408514e-02f, -2.67529307e-02f, -2.71613007e-02f, -2.75659679e-02f, - -2.79668938e-02f, -2.83639683e-02f, -2.87572005e-02f, -2.91465063e-02f, -2.95318218e-02f, -2.99131497e-02f, - -3.02904053e-02f, -3.06635679e-02f, -3.10324988e-02f, -3.13973391e-02f, -3.17578262e-02f, -3.21140642e-02f, - -3.24659140e-02f, -3.28134068e-02f, -3.31564690e-02f, -3.34950508e-02f, -3.38290958e-02f, -3.41585789e-02f, - -3.44835399e-02f, -3.48037171e-02f, -3.51193059e-02f, -3.54301016e-02f, -3.57362158e-02f, -3.60375290e-02f, - -3.63339504e-02f, -3.66254924e-02f, -3.69121617e-02f, -3.71938428e-02f, -3.74705630e-02f, -3.77422570e-02f, - -3.80089127e-02f, -3.82704689e-02f, -3.85269416e-02f, -3.87782032e-02f, -3.90243221e-02f, -3.92652338e-02f, - -3.95008992e-02f, -3.97312729e-02f, -3.99563822e-02f, -4.01761466e-02f, -4.03906073e-02f, -4.05996218e-02f, - -4.08032391e-02f, -4.10014681e-02f, -4.11942039e-02f, -4.13814851e-02f, -4.15632917e-02f, -4.17395509e-02f, - -4.19102414e-02f, -4.20754258e-02f, -4.22349697e-02f, -4.23890016e-02f, -4.25373605e-02f, -4.26800135e-02f, - -4.28171026e-02f, -4.29485203e-02f, -4.30742475e-02f, -4.31942683e-02f, -4.33085546e-02f, -4.34171792e-02f, - -4.35199872e-02f, -4.36170833e-02f, -4.37084277e-02f, -4.37940290e-02f, -4.38737967e-02f, -4.39477984e-02f, - -4.40160249e-02f, -4.40784200e-02f, -4.41350559e-02f, -4.41858018e-02f, -4.42307931e-02f, -4.42700042e-02f, - -4.43032845e-02f, -4.43308166e-02f, -4.43525043e-02f, -4.43683353e-02f, -4.43783535e-02f, -4.43825936e-02f, - -4.43809501e-02f, -4.43734974e-02f, -4.43602289e-02f, -4.43411395e-02f, -4.43162414e-02f, -4.42855523e-02f, - -4.42490065e-02f, -4.42067641e-02f, -4.41586644e-02f, -4.41048195e-02f, -4.40451981e-02f, -4.39798011e-02f, - -4.39086981e-02f, -4.38317788e-02f, -4.37492249e-02f, -4.36609262e-02f, -4.35669538e-02f, -4.34672367e-02f, - -4.33618744e-02f, -4.32509117e-02f, -4.31343017e-02f, -4.30120363e-02f, -4.28842150e-02f, -4.27507385e-02f, - -4.26117781e-02f, -4.24672328e-02f, -4.23171601e-02f, -4.21616594e-02f, -4.20006183e-02f, -4.18341163e-02f, - -4.16622553e-02f, -4.14849538e-02f, -4.13022654e-02f, -4.11142151e-02f, -4.09208685e-02f, -4.07221733e-02f, - -4.05182615e-02f, -4.03090623e-02f, -4.00947070e-02f, -3.98751262e-02f, -3.96503920e-02f, -3.94205563e-02f, - -3.91856233e-02f, -3.89456268e-02f, -3.87006058e-02f, -3.84506535e-02f, -3.81956683e-02f, -3.79357983e-02f, - -3.76710594e-02f, -3.74014442e-02f, -3.71270366e-02f, -3.68478593e-02f, -3.65639447e-02f, -3.62753546e-02f, - -3.59820957e-02f, -3.56842071e-02f, -3.53817460e-02f, -3.50748080e-02f, -3.47632985e-02f, -3.44474323e-02f, - -3.41270807e-02f, -3.38024038e-02f, -3.34733850e-02f, -3.31401343e-02f, -3.28026457e-02f, -3.24609382e-02f, - -3.21151707e-02f, -3.17652637e-02f, -3.14113289e-02f, -3.10534034e-02f, -3.06915435e-02f, -3.03257503e-02f, - -2.99561652e-02f, -2.95827337e-02f, -2.92056114e-02f, -2.88247591e-02f, -2.84402855e-02f, -2.80521904e-02f, - -2.76605857e-02f, -2.72654939e-02f, -2.68669872e-02f, -2.64650786e-02f, -2.60598152e-02f, -2.56513197e-02f, - -2.52396134e-02f, -2.48246962e-02f, -2.44067626e-02f, -2.39857153e-02f, -2.35617028e-02f, -2.31346876e-02f, - -2.27049078e-02f, -2.22722128e-02f, -2.18368459e-02f, -2.13986802e-02f, -2.09578934e-02f, -2.05145781e-02f, - -2.00686625e-02f, -1.96203632e-02f, -1.91695407e-02f, -1.87164706e-02f, -1.82610352e-02f, -1.78034072e-02f, - -1.73436532e-02f, -1.68816928e-02f, -1.64177981e-02f, -1.59518621e-02f, -1.54840040e-02f, -1.50142983e-02f, - -1.45427928e-02f, -1.40695958e-02f, -1.35946681e-02f, -1.31181593e-02f, -1.26401032e-02f, -1.21605570e-02f, - -1.16795866e-02f, -1.11973188e-02f, -1.07136787e-02f, -1.02288957e-02f, -9.74287308e-03f, -9.25579171e-03f, - -8.76767385e-03f, -8.27860602e-03f, -7.78864440e-03f, -7.29774737e-03f, -6.80618339e-03f, -6.31385495e-03f, - -5.82089853e-03f, -5.32736723e-03f, -4.83330658e-03f, -4.33882252e-03f, -3.84391825e-03f, -3.34873531e-03f, - -2.85322180e-03f, -2.35761028e-03f, -1.86181620e-03f, -1.36600561e-03f, -8.70173075e-04f, -3.74410785e-04f, - 1.21213558e-04f, 6.16621277e-04f, 1.11176622e-03f, 1.60657531e-03f, 2.10098665e-03f, 2.59496722e-03f, - 3.08840860e-03f, 3.58127168e-03f, 4.07342890e-03f, 4.56487047e-03f, 5.05558091e-03f, 5.54542258e-03f, - 6.03432691e-03f, 6.52226892e-03f, 7.00920712e-03f, 7.49499595e-03f, 7.97961061e-03f, 8.46303068e-03f, - 8.94512842e-03f, 9.42593396e-03f, 9.90521034e-03f, 1.03831100e-02f, 1.08593924e-02f, 1.13341155e-02f, - 1.18071410e-02f, 1.22784446e-02f, 1.27479721e-02f, 1.32156493e-02f, 1.36814006e-02f, 1.41451657e-02f, - 1.46068950e-02f, 1.50666096e-02f, 1.55241279e-02f, 1.59793597e-02f, 1.64324267e-02f, 1.68830736e-02f, - 1.73314038e-02f, 1.77772624e-02f, 1.82206106e-02f, 1.86614137e-02f, 1.90996099e-02f, 1.95350663e-02f, - 1.99678717e-02f, 2.03978347e-02f, 2.08249878e-02f, 2.12492238e-02f, 2.16705441e-02f, 2.20888197e-02f, - 2.25040215e-02f, 2.29161593e-02f, 2.33250558e-02f, 2.37308116e-02f, 2.41332668e-02f, 2.45324819e-02f, - 2.49281722e-02f, 2.53204816e-02f, 2.57093487e-02f, 2.60946742e-02f, 2.64764614e-02f, 2.68545908e-02f, - 2.72290322e-02f, 2.75997743e-02f, 2.79667387e-02f, 2.83299252e-02f, 2.86892209e-02f, 2.90446388e-02f, - 2.93960375e-02f, 2.97435238e-02f, 3.00869105e-02f, 3.04262462e-02f, 3.07614098e-02f, 3.10924544e-02f, - 3.14192610e-02f, 3.17418568e-02f, 3.20600698e-02f, 3.23740294e-02f, 3.26835915e-02f, 3.29887067e-02f, - 3.32894577e-02f, 3.35856312e-02f, 3.38773054e-02f, 3.41644441e-02f, 3.44469606e-02f, 3.47248261e-02f, - 3.49980424e-02f, 3.52665498e-02f, 3.55302849e-02f, 3.57893093e-02f, 3.60435171e-02f, 3.62928660e-02f, - 3.65373609e-02f, 3.67769475e-02f, 3.70116347e-02f, 3.72413781e-02f, 3.74661295e-02f, 3.76858318e-02f, - 3.79005179e-02f, 3.81101371e-02f, 3.83146876e-02f, 3.85140896e-02f, 3.87083664e-02f, 3.88974904e-02f, - 3.90814347e-02f, 3.92601660e-02f, 3.94336525e-02f, 3.96018706e-02f, 3.97648846e-02f, 3.99225680e-02f, - 4.00749489e-02f, 4.02219655e-02f, 4.03636822e-02f, 4.04999999e-02f, 4.06310146e-02f, 4.07565606e-02f, - 4.08767186e-02f, 4.09914247e-02f, 4.11007901e-02f, 4.12046562e-02f, 4.13030429e-02f, 4.13960181e-02f, - 4.14834607e-02f, 4.15654042e-02f, 4.16418796e-02f, 4.17128614e-02f, 4.17783281e-02f, 4.18382352e-02f, - 4.18926432e-02f, 4.19415283e-02f, 4.19848866e-02f, 4.20227165e-02f, 4.20549497e-02f, 4.20816983e-02f, - 4.21028500e-02f, 4.21184891e-02f, 4.21285845e-02f, 4.21331217e-02f, 4.21321445e-02f, 4.21255744e-02f, - 4.21134719e-02f, 4.20958846e-02f, 4.20727201e-02f, 4.20440868e-02f, 4.20098563e-02f, 4.19701761e-02f, - 4.19249486e-02f, 4.18742297e-02f, 4.18180615e-02f, 4.17563612e-02f, 4.16892353e-02f, 4.16166093e-02f, - 4.15386032e-02f, 4.14550641e-02f, 4.13661502e-02f, 4.12718591e-02f, 4.11721430e-02f, 4.10670785e-02f, - 4.09565759e-02f, 4.08407977e-02f, 4.07196495e-02f, 4.05932342e-02f, 4.04615062e-02f, 4.03244790e-02f, - 4.01822309e-02f, 4.00347448e-02f, 3.98820132e-02f, 3.97241266e-02f, 3.95611002e-02f, 3.93928527e-02f, - 3.92195610e-02f, 3.90410941e-02f, 3.88576633e-02f, 3.86690878e-02f, 3.84755564e-02f, 3.82769984e-02f, - 3.80735315e-02f, 3.78651039e-02f, 3.76517514e-02f, 3.74335333e-02f, 3.72104923e-02f, 3.69826198e-02f, - 3.67499817e-02f, 3.65125758e-02f, 3.62704675e-02f, 3.60236927e-02f, 3.57722302e-02f, 3.55162051e-02f, - 3.52555602e-02f, 3.49903876e-02f, 3.47207327e-02f, 3.44465905e-02f, 3.41680183e-02f, 3.38850829e-02f, - 3.35977255e-02f, 3.33061287e-02f, 3.30101977e-02f, 3.27100735e-02f, 3.24057640e-02f, 3.20972847e-02f, - 3.17846857e-02f, 3.14680574e-02f, 3.11473876e-02f, 3.08227620e-02f, 3.04941690e-02f, 3.01616618e-02f, - 2.98253916e-02f, 2.94852444e-02f, 2.91413815e-02f, 2.87938239e-02f, 2.84425957e-02f, 2.80877568e-02f, - 2.77293306e-02f, 2.73674159e-02f, 2.70020247e-02f, 2.66332211e-02f, 2.62610753e-02f, 2.58855701e-02f, - 2.55068575e-02f, 2.51248633e-02f, 2.47397340e-02f, 2.43515178e-02f, 2.39601920e-02f, 2.35658880e-02f, - 2.31686505e-02f, 2.27684471e-02f, 2.23654846e-02f, 2.19596667e-02f, 2.15511569e-02f, 2.11399453e-02f, - 2.07260865e-02f, 2.03096904e-02f, 1.98907010e-02f, 1.94693391e-02f, 1.90455509e-02f, 1.86193914e-02f, - 1.81909509e-02f, 1.77602779e-02f, 1.73274401e-02f, 1.68924678e-02f, 1.64554983e-02f, 1.60164319e-02f, - 1.55754722e-02f, 1.51325854e-02f, 1.46879534e-02f, 1.42415024e-02f, 1.37933311e-02f, 1.33435346e-02f, - 1.28921729e-02f, 1.24392635e-02f, 1.19848478e-02f, 1.15290853e-02f, 1.10719409e-02f, 1.06135533e-02f, - 1.01539005e-02f, 9.69306680e-03f, 9.23115325e-03f, 8.76828698e-03f, 8.30428076e-03f, 7.83947696e-03f, - 7.37374317e-03f, 6.90725848e-03f, 6.44002866e-03f, 5.97212946e-03f, 5.50356383e-03f, 5.03452912e-03f, - 4.56498546e-03f, 4.09499762e-03f, 3.62466869e-03f, 3.15408390e-03f, 2.68311546e-03f, 2.21212174e-03f, - 1.74093301e-03f, 1.26976103e-03f, 7.98534734e-04f, 3.27387905e-04f, -1.43588190e-04f, -6.14396280e-04f, - -1.08492468e-03f, -1.55519199e-03f, -2.02499505e-03f, -2.49441261e-03f, -2.96329669e-03f, -3.43161913e-03f, - -3.89934051e-03f, -4.36628942e-03f, -4.83256241e-03f, -5.29803068e-03f, -5.76256090e-03f, -6.22623559e-03f, - -6.68885011e-03f, -7.15046049e-03f, -7.61093179e-03f, -8.07020586e-03f, -8.52826436e-03f, -8.98503161e-03f, - -9.44043043e-03f, -9.89444508e-03f, -1.03469104e-02f, -1.07979117e-02f, -1.12473375e-02f, -1.16950534e-02f, - -1.21410996e-02f, -1.25853391e-02f, -1.30277930e-02f, -1.34683582e-02f, -1.39069430e-02f, -1.43435829e-02f, - -1.47781293e-02f, -1.52106099e-02f, -1.56408931e-02f, -1.60689546e-02f, -1.64947176e-02f, -1.69182119e-02f, - -1.73392539e-02f, -1.77578631e-02f, -1.81739841e-02f, -1.85875699e-02f, -1.89985738e-02f, -1.94068530e-02f, - -1.98124640e-02f, -2.02152871e-02f, -2.06153313e-02f, -2.10125054e-02f, -2.14067074e-02f, -2.17979669e-02f, - -2.21862358e-02f, -2.25714416e-02f, -2.29534751e-02f, -2.33323797e-02f, -2.37080777e-02f, -2.40804799e-02f, - -2.44495675e-02f, -2.48153014e-02f, -2.51776748e-02f, -2.55365459e-02f, -2.58919207e-02f, -2.62437181e-02f, - -2.65919885e-02f, -2.69366220e-02f, -2.72775437e-02f, -2.76147110e-02f, -2.79481964e-02f, -2.82778165e-02f, - -2.86036057e-02f, -2.89254763e-02f, -2.92434731e-02f, -2.95574610e-02f, -2.98674325e-02f, -3.01733399e-02f, - -3.04751296e-02f, -3.07728959e-02f, -3.10664240e-02f, -3.13557334e-02f, -3.16408386e-02f, -3.19216276e-02f, - -3.21981560e-02f, -3.24702964e-02f, -3.27380555e-02f, -3.30014380e-02f, -3.32603372e-02f, -3.35147711e-02f, - -3.37646611e-02f, -3.40100968e-02f, -3.42508573e-02f, -3.44870545e-02f, -3.47186217e-02f, -3.49455160e-02f, - -3.51677555e-02f, -3.53852014e-02f, -3.55979739e-02f, -3.58059109e-02f, -3.60090989e-02f, -3.62074797e-02f, - -3.64009621e-02f, -3.65896075e-02f, -3.67733477e-02f, -3.69522009e-02f, -3.71260741e-02f, -3.72950126e-02f, - -3.74589630e-02f, -3.76179256e-02f, -3.77718451e-02f, -3.79207528e-02f, -3.80645999e-02f, -3.82033629e-02f, - -3.83370719e-02f, -3.84656874e-02f, -3.85891166e-02f, -3.87074600e-02f, -3.88206752e-02f, -3.89286668e-02f, - -3.90315325e-02f, -3.91291963e-02f, -3.92217103e-02f, -3.93089773e-02f, -3.93910171e-02f, -3.94678412e-02f, - -3.95394762e-02f, -3.96058618e-02f, -3.96669924e-02f, -3.97228243e-02f, -3.97734603e-02f, -3.98188239e-02f, - -3.98588816e-02f, -3.98936946e-02f, -3.99232772e-02f, -3.99475561e-02f, -3.99665285e-02f, -3.99802503e-02f, - -3.99886991e-02f, -3.99918905e-02f, -3.99897828e-02f, -3.99824025e-02f, -3.99697450e-02f, -3.99518750e-02f, - -3.99286777e-02f, -3.99002667e-02f, -3.98666497e-02f, -3.98276954e-02f, -3.97835798e-02f, -3.97341718e-02f, - -3.96796125e-02f, -3.96197985e-02f, -3.95547681e-02f, -3.94845904e-02f, -3.94091982e-02f, -3.93287162e-02f, - -3.92429609e-02f, -3.91521529e-02f, -3.90561964e-02f, -3.89551155e-02f, -3.88489281e-02f, -3.87376955e-02f, - -3.86213743e-02f, -3.84999635e-02f, -3.83736147e-02f, -3.82421712e-02f, -3.81058072e-02f, -3.79643826e-02f, - -3.78180550e-02f, -3.76668010e-02f, -3.75106815e-02f, -3.73495865e-02f, -3.71837040e-02f, -3.70128959e-02f, - -3.68373671e-02f, -3.66569527e-02f, -3.64719066e-02f, -3.62819699e-02f, -3.60873935e-02f, -3.58881266e-02f, - -3.56842108e-02f, -3.54756832e-02f, -3.52625264e-02f, -3.50447878e-02f, -3.48225523e-02f, -3.45957409e-02f, - -3.43645191e-02f, -3.41288507e-02f, -3.38887383e-02f, -3.36443014e-02f, -3.33954100e-02f, -3.31423355e-02f, - -3.28849100e-02f, -3.26232988e-02f, -3.23574406e-02f, -3.20874197e-02f, -3.18132521e-02f, -3.15350333e-02f, - -3.12527580e-02f, -3.09664187e-02f, -3.06761915e-02f, -3.03819630e-02f, -3.00838581e-02f, -2.97818899e-02f, - -2.94760960e-02f, -2.91665641e-02f, -2.88532863e-02f, -2.85363266e-02f, -2.82157140e-02f, -2.78915054e-02f, - -2.75637165e-02f, -2.72324830e-02f, -2.68977047e-02f, -2.65595786e-02f, -2.62180310e-02f, -2.58731677e-02f, - -2.55249759e-02f, -2.51736500e-02f, -2.48190383e-02f, -2.44613879e-02f, -2.41005148e-02f, -2.37366809e-02f, - -2.33698761e-02f, -2.30001161e-02f, -2.26274011e-02f, -2.22518993e-02f, -2.18735959e-02f, -2.14925161e-02f, - -2.11088237e-02f, -2.07223807e-02f, -2.03334802e-02f, -1.99419388e-02f, -1.95479549e-02f, -1.91515295e-02f, - -1.87527848e-02f, -1.83516250e-02f, -1.79482737e-02f, -1.75426496e-02f, -1.71349070e-02f, -1.67250443e-02f, - -1.63131505e-02f, -1.58991873e-02f, -1.54833704e-02f, -1.50656498e-02f, -1.46460676e-02f, -1.42247146e-02f, - -1.38016889e-02f, -1.33769349e-02f, -1.29506513e-02f, -1.25227798e-02f, -1.20934202e-02f, -1.16626249e-02f, - -1.12304792e-02f, -1.07969714e-02f, -1.03622448e-02f, -9.92629477e-03f, -9.48921189e-03f, -9.05103869e-03f, - -8.61184534e-03f, -8.17164329e-03f, -7.73056287e-03f, -7.28864541e-03f, -6.84590211e-03f, -6.40247915e-03f, - -5.95827344e-03f, -5.51353459e-03f, -5.06821233e-03f, -4.62241765e-03f, -4.17614199e-03f, -3.72951046e-03f, - -3.28251601e-03f, -2.83534691e-03f, -2.38788291e-03f, -1.94026118e-03f, -1.49265072e-03f, -1.04495729e-03f, - -5.97289539e-04f, -1.49699294e-04f, 2.97692630e-04f, 7.44901807e-04f, 1.19186601e-03f, 1.63844622e-03f, - 2.08468834e-03f, 2.53043215e-03f, 2.97576020e-03f, 3.42047846e-03f, 3.86460421e-03f, 4.30798890e-03f, - 4.75069370e-03f, 5.19254548e-03f, 5.63358995e-03f, 6.07373667e-03f, 6.51288506e-03f, 6.95099308e-03f, - 7.38804080e-03f, 7.82397028e-03f, 8.25864306e-03f, 8.69213108e-03f, 9.12424933e-03f, 9.55504603e-03f, - 9.98440015e-03f, 1.04122588e-02f, 1.08385766e-02f, 1.12633093e-02f, 1.16864097e-02f, 1.21077749e-02f, - 1.25274398e-02f, 1.29452309e-02f, 1.33612003e-02f, 1.37751945e-02f, 1.41872478e-02f, 1.45973194e-02f, - 1.50052154e-02f, 1.54110755e-02f, 1.58146392e-02f, 1.62160450e-02f, 1.66151053e-02f, 1.70118497e-02f, - 1.74061996e-02f, 1.77980810e-02f, 1.81875188e-02f, 1.85743309e-02f, 1.89585758e-02f, 1.93401848e-02f, - 1.97190858e-02f, 2.00952833e-02f, 2.04686159e-02f, 2.08391273e-02f, 2.12067436e-02f, 2.15714441e-02f, - 2.19331482e-02f, 2.22918146e-02f, 2.26473983e-02f, 2.29998670e-02f, 2.33491592e-02f, 2.36952407e-02f, - 2.40380405e-02f, 2.43775659e-02f, 2.47137454e-02f, 2.50465323e-02f, 2.53758544e-02f, 2.57017227e-02f, - 2.60240877e-02f, 2.63428757e-02f, 2.66580782e-02f, 2.69696661e-02f, 2.72775020e-02f, 2.75816677e-02f, - 2.78820744e-02f, 2.81786759e-02f, 2.84714811e-02f, 2.87603170e-02f, 2.90453586e-02f, 2.93264011e-02f, - 2.96034942e-02f, 2.98765362e-02f, 3.01455631e-02f, 3.04104595e-02f, 3.06713074e-02f, 3.09279391e-02f, - 3.11804899e-02f, 3.14287221e-02f, 3.16727264e-02f, 3.19124841e-02f, 3.21479663e-02f, 3.23790618e-02f, - 3.26057961e-02f, 3.28281718e-02f, 3.30461215e-02f, 3.32595922e-02f, 3.34686104e-02f, 3.36731086e-02f, - 3.38731748e-02f, 3.40686071e-02f, 3.42594244e-02f, 3.44457351e-02f, 3.46273885e-02f, 3.48044193e-02f, - 3.49767710e-02f, 3.51444206e-02f, 3.53074004e-02f, 3.54656427e-02f, 3.56191436e-02f, 3.57678592e-02f, - 3.59118434e-02f, 3.60509626e-02f, 3.61853265e-02f, 3.63148179e-02f, 3.64395267e-02f, 3.65593343e-02f, - 3.66742313e-02f, 3.67842902e-02f, 3.68894793e-02f, 3.69896625e-02f, 3.70849929e-02f, 3.71753786e-02f, - 3.72608273e-02f, 3.73412921e-02f, 3.74168016e-02f, 3.74873565e-02f, 3.75529348e-02f, 3.76135420e-02f, - 3.76691122e-02f, 3.77197046e-02f, 3.77653227e-02f, 3.78059024e-02f, 3.78415160e-02f, 3.78720351e-02f, - 3.78976353e-02f, 3.79181833e-02f, 3.79336675e-02f, 3.79442144e-02f, 3.79496743e-02f, 3.79501834e-02f, - 3.79456915e-02f, 3.79361375e-02f, 3.79215391e-02f, 3.79020325e-02f, 3.78774312e-02f, 3.78479094e-02f, - 3.78134073e-02f, 3.77738493e-02f, 3.77293575e-02f, 3.76799011e-02f, 3.76255148e-02f, 3.75661392e-02f, - 3.75018334e-02f, 3.74326251e-02f, 3.73584348e-02f, 3.72793891e-02f, 3.71954356e-02f, 3.71066069e-02f, - 3.70129302e-02f, 3.69143543e-02f, 3.68109405e-02f, 3.67027388e-02f, 3.65897207e-02f, 3.64718883e-02f, - 3.63492791e-02f, 3.62219753e-02f, 3.60898426e-02f, 3.59531151e-02f, 3.58115783e-02f, 3.56654079e-02f, - 3.55145806e-02f, 3.53591219e-02f, 3.51990403e-02f, 3.50343592e-02f, 3.48651407e-02f, 3.46913911e-02f, - 3.45130741e-02f, 3.43302906e-02f, 3.41430671e-02f, 3.39513907e-02f, 3.37552593e-02f, 3.35547870e-02f, - 3.33499199e-02f, 3.31407512e-02f, 3.29273120e-02f, 3.27095616e-02f, 3.24876044e-02f, 3.22613932e-02f, - 3.20310468e-02f, 3.17965531e-02f, 3.15579152e-02f, 3.13152482e-02f, 3.10684712e-02f, 3.08177314e-02f, - 3.05630079e-02f, 3.03043332e-02f, 3.00417882e-02f, 2.97753013e-02f, 2.95050577e-02f, 2.92309435e-02f, - 2.89531575e-02f, 2.86715787e-02f, 2.83863717e-02f, 2.80975071e-02f, 2.78050192e-02f, 2.75089685e-02f, - 2.72094098e-02f, 2.69063767e-02f, 2.65998810e-02f, 2.62900070e-02f, 2.59767878e-02f, 2.56602328e-02f, - 2.53404111e-02f, 2.50173620e-02f, 2.46911407e-02f, 2.43617749e-02f, 2.40293261e-02f, 2.36937859e-02f, - 2.33553034e-02f, 2.30138134e-02f, 2.26694465e-02f, 2.23221676e-02f, 2.19721599e-02f, 2.16192841e-02f, - 2.12637667e-02f, 2.09055097e-02f, 2.05446679e-02f, 2.01812780e-02f, 1.98152662e-02f, 1.94468374e-02f, - 1.90759686e-02f, 1.87027040e-02f, 1.83271444e-02f, 1.79492754e-02f, 1.75692070e-02f, 1.71869386e-02f, - 1.68025462e-02f, 1.64160881e-02f, 1.60276417e-02f, 1.56371239e-02f, 1.52447784e-02f, 1.48505372e-02f, - 1.44545257e-02f, 1.40567265e-02f, 1.36572037e-02f, 1.32560196e-02f, 1.28532354e-02f, 1.24489513e-02f, - 1.20431450e-02f, 1.16359654e-02f, 1.12272818e-02f, 1.08173233e-02f, 1.04061003e-02f, 9.99371926e-03f, - 9.58009820e-03f, 9.16541300e-03f, 8.74961509e-03f, 8.33285253e-03f, 7.91516681e-03f, 7.49659132e-03f, - 7.07715356e-03f, 6.65693224e-03f, 6.23603555e-03f, 5.81448493e-03f, 5.39228369e-03f, 4.96955916e-03f, - 4.54630220e-03f, 4.12266461e-03f, 3.69857954e-03f, 3.27424810e-03f, 2.84955747e-03f, 2.42470997e-03f, - 1.99969052e-03f, 1.57453530e-03f, 1.14939405e-03f, 7.24246312e-04f, 2.99137206e-04f, -1.25830140e-04f, - -5.50607251e-04f, -9.75186924e-04f, -1.39943020e-03f, -1.82333806e-03f, -2.24685204e-03f, -2.66990785e-03f, - -3.09244421e-03f, -3.51441052e-03f, -3.93576180e-03f, -4.35637358e-03f, -4.77636309e-03f, -5.19545283e-03f, - -5.61376703e-03f, -6.03109181e-03f, -6.44754238e-03f, -6.86295934e-03f, -7.27728924e-03f, -7.69049973e-03f, - -8.10256003e-03f, -8.51341173e-03f, -8.92292402e-03f, -9.33109503e-03f, -9.73791415e-03f, -1.01432714e-02f, - -1.05471689e-02f, -1.09494827e-02f, -1.13501590e-02f, -1.17492540e-02f, -1.21465856e-02f, -1.25422078e-02f, - -1.29359876e-02f, -1.33279112e-02f, -1.37179123e-02f, -1.41060043e-02f, -1.44919816e-02f, -1.48759784e-02f, - -1.52578595e-02f, -1.56375269e-02f, -1.60149962e-02f, -1.63902237e-02f, -1.67631333e-02f, -1.71336625e-02f, - -1.75017897e-02f, -1.78674676e-02f, -1.82306929e-02f, -1.85912732e-02f, -1.89493455e-02f, -1.93047057e-02f, - -1.96574156e-02f, -2.00073761e-02f, -2.03545482e-02f, -2.06989087e-02f, -2.10404187e-02f, -2.13789704e-02f, - -2.17145975e-02f, -2.20472034e-02f, -2.23767564e-02f, -2.27032719e-02f, -2.30266359e-02f, -2.33468138e-02f, - -2.36638280e-02f, -2.39775139e-02f, -2.42879682e-02f, -2.45950474e-02f, -2.48987716e-02f, -2.51991238e-02f, - -2.54960026e-02f, -2.57893741e-02f, -2.60792082e-02f, -2.63655870e-02f, -2.66482363e-02f, -2.69273641e-02f, - -2.72027527e-02f, -2.74743999e-02f, -2.77424085e-02f, -2.80065886e-02f, -2.82669743e-02f, -2.85235311e-02f, - -2.87761910e-02f, -2.90249437e-02f, -2.92697916e-02f, -2.95106533e-02f, -2.97475482e-02f, -2.99803911e-02f, - -3.02091621e-02f, -3.04338786e-02f, -3.06544938e-02f, -3.08709264e-02f, -3.10832267e-02f, -3.12913288e-02f, - -3.14952003e-02f, -3.16948357e-02f, -3.18901660e-02f, -3.20812355e-02f, -3.22679885e-02f, -3.24504356e-02f, - -3.26284605e-02f, -3.28021365e-02f, -3.29713499e-02f, -3.31362329e-02f, -3.32965878e-02f, -3.34524976e-02f, - -3.36039174e-02f, -3.37508691e-02f, -3.38932427e-02f, -3.40311229e-02f, -3.41644218e-02f, -3.42931774e-02f, - -3.44173419e-02f, -3.45368621e-02f, -3.46517923e-02f, -3.47620885e-02f, -3.48677911e-02f, -3.49687842e-02f, - -3.50651432e-02f, -3.51567783e-02f, -3.52437772e-02f, -3.53260705e-02f, -3.54036463e-02f, -3.54764954e-02f, - -3.55446539e-02f, -3.56080953e-02f, -3.56667016e-02f, -3.57206849e-02f, -3.57698565e-02f, -3.58143032e-02f, - -3.58539597e-02f, -3.58889103e-02f, -3.59190456e-02f, -3.59444590e-02f, -3.59650977e-02f, -3.59809382e-02f, - -3.59920300e-02f, -3.59983756e-02f, -3.59999125e-02f, -3.59967329e-02f, -3.59887344e-02f, -3.59760381e-02f, - -3.59585548e-02f, -3.59363223e-02f, -3.59093515e-02f, -3.58776121e-02f, -3.58411756e-02f, -3.57999395e-02f, - -3.57540544e-02f, -3.57034544e-02f, -3.56481299e-02f, -3.55881336e-02f, -3.55233487e-02f, -3.54540226e-02f, - -3.53799374e-02f, -3.53012931e-02f, -3.52178742e-02f, -3.51299483e-02f, -3.50373170e-02f, -3.49401557e-02f, - -3.48383873e-02f, -3.47320155e-02f, -3.46211001e-02f, -3.45056827e-02f, -3.43857075e-02f, -3.42611967e-02f, - -3.41323091e-02f, -3.39988434e-02f, -3.38609854e-02f, -3.37186705e-02f, -3.35719310e-02f, -3.34208815e-02f, - -3.32654002e-02f, -3.31055870e-02f, -3.29414534e-02f, -3.27730458e-02f, -3.26003397e-02f, -3.24234054e-02f, - -3.22422664e-02f, -3.20568581e-02f, -3.18673427e-02f, -3.16736614e-02f, -3.14758507e-02f, -3.12739467e-02f, - -3.10679983e-02f, -3.08580113e-02f, -3.06440558e-02f, -3.04260744e-02f, -3.02041732e-02f, -2.99783222e-02f, - -2.97486657e-02f, -2.95151181e-02f, -2.92777268e-02f, -2.90365811e-02f, -2.87916823e-02f, -2.85430545e-02f, - -2.82907877e-02f, -2.80348109e-02f, -2.77752595e-02f, -2.75121237e-02f, -2.72454072e-02f, -2.69752758e-02f, - -2.67016044e-02f, -2.64245472e-02f, -2.61440626e-02f, -2.58602485e-02f, -2.55730926e-02f, -2.52827047e-02f, - -2.49890379e-02f, -2.46922324e-02f, -2.43921929e-02f, -2.40891208e-02f, -2.37828904e-02f, -2.34737214e-02f, - -2.31615121e-02f, -2.28463740e-02f, -2.25283178e-02f, -2.22074093e-02f, -2.18836933e-02f, -2.15571691e-02f, - -2.12279753e-02f, -2.08960460e-02f, -2.05615135e-02f, -2.02243244e-02f, -1.98847045e-02f, -1.95424611e-02f, - -1.91978514e-02f, -1.88507841e-02f, -1.85013631e-02f, -1.81496559e-02f, -1.77956554e-02f, -1.74394017e-02f, - -1.70809940e-02f, -1.67205298e-02f, -1.63579422e-02f, -1.59933215e-02f, -1.56267101e-02f, -1.52582232e-02f, - -1.48878041e-02f, -1.45156066e-02f, -1.41415540e-02f, -1.37658786e-02f, -1.33884570e-02f, -1.30094352e-02f, - -1.26288159e-02f, -1.22466388e-02f, -1.18630424e-02f, -1.14780118e-02f, -1.10916190e-02f, -1.07038687e-02f, - -1.03148963e-02f, -9.92470515e-03f, -9.53331954e-03f, -9.14083232e-03f, -8.74728260e-03f, -8.35275342e-03f, - -7.95726787e-03f, -7.56080375e-03f, -7.16360956e-03f, -6.76552825e-03f, -6.36677435e-03f, -5.96726304e-03f, - -5.56716903e-03f, -5.16648509e-03f, -4.76522805e-03f, -4.36356898e-03f, -3.96141267e-03f, -3.55891082e-03f, - -3.15612842e-03f, -2.75307110e-03f, -2.34979109e-03f, -1.94629144e-03f, -1.54281850e-03f, -1.13922044e-03f, - -7.35634706e-04f, -3.32099420e-04f, 7.12856509e-05f, 4.74559316e-04f, 8.77559135e-04f, 1.28032218e-03f, - 1.68275904e-03f, 2.08477857e-03f, 2.48641762e-03f, 2.88751125e-03f, 3.28814672e-03f, 3.68814426e-03f, - 4.08751819e-03f, 4.48615940e-03f, 4.88410119e-03f, 5.28121721e-03f, 5.67747438e-03f, 6.07283991e-03f, - 6.46720937e-03f, 6.86064115e-03f, 7.25294544e-03f, 7.64416396e-03f, 8.03424212e-03f, 8.42303179e-03f, - 8.81064981e-03f, 9.19690944e-03f, 9.58180083e-03f, 9.96524781e-03f, 1.03472702e-02f, 1.07277487e-02f, - 1.11066493e-02f, 1.14839433e-02f, 1.18595706e-02f, 1.22334978e-02f, 1.26056532e-02f, 1.29759687e-02f, - 1.33444544e-02f, 1.37110094e-02f, 1.40756199e-02f, 1.44382235e-02f, 1.47987730e-02f, 1.51572059e-02f, - 1.55135117e-02f, 1.58676034e-02f, 1.62194767e-02f, 1.65690505e-02f, 1.69163382e-02f, 1.72611805e-02f, - 1.76036419e-02f, 1.79436034e-02f, 1.82811161e-02f, 1.86160563e-02f, 1.89483543e-02f, 1.92780478e-02f, - 1.96050825e-02f, 1.99293771e-02f, 2.02508882e-02f, 2.05696155e-02f, 2.08854535e-02f, 2.11984606e-02f, - 2.15084839e-02f, 2.18155777e-02f, 2.21196200e-02f, 2.24206417e-02f, 2.27185973e-02f, 2.30133952e-02f, - 2.33050655e-02f, 2.35935022e-02f, 2.38786657e-02f, 2.41606180e-02f, 2.44392165e-02f, 2.47144950e-02f, - 2.49863981e-02f, 2.52548911e-02f, 2.55198955e-02f, 2.57814642e-02f, 2.60394823e-02f, 2.62939385e-02f, - 2.65448337e-02f, 2.67921043e-02f, 2.70357448e-02f, 2.72757128e-02f, 2.75119540e-02f, 2.77444291e-02f, - 2.79731795e-02f, 2.81981824e-02f, 2.84192597e-02f, 2.86365652e-02f, 2.88499170e-02f, 2.90594644e-02f, - 2.92649801e-02f, 2.94665879e-02f, 2.96642071e-02f, 2.98578136e-02f, 3.00473708e-02f, 3.02329153e-02f, - 3.04143332e-02f, 3.05917179e-02f, 3.07648820e-02f, 3.09340050e-02f, 3.10989083e-02f, 3.12596334e-02f, - 3.14161606e-02f, 3.15684495e-02f, 3.17165056e-02f, 3.18602806e-02f, 3.19998114e-02f, 3.21350329e-02f, - 3.22659250e-02f, 3.23925242e-02f, 3.25147454e-02f, 3.26326298e-02f, 3.27461813e-02f, 3.28553126e-02f, - 3.29600323e-02f, 3.30603410e-02f, 3.31562534e-02f, 3.32477141e-02f, 3.33347480e-02f, 3.34173462e-02f, - 3.34954121e-02f, 3.35691117e-02f, 3.36382668e-02f, 3.37029867e-02f, 3.37631537e-02f, 3.38188181e-02f, - 3.38700260e-02f, 3.39167037e-02f, 3.39589355e-02f, 3.39965197e-02f, 3.40296499e-02f, 3.40582870e-02f, - 3.40823550e-02f, 3.41018821e-02f, 3.41169618e-02f, 3.41274365e-02f, 3.41333973e-02f, 3.41348660e-02f, - 3.41317843e-02f, 3.41241436e-02f, 3.41120932e-02f, 3.40954107e-02f, 3.40742985e-02f, 3.40485927e-02f, - 3.40184583e-02f, 3.39837495e-02f, 3.39446372e-02f, 3.39009897e-02f, 3.38529011e-02f, 3.38003110e-02f, - 3.37432378e-02f, 3.36817663e-02f, 3.36158190e-02f, 3.35454687e-02f, 3.34706950e-02f, 3.33914955e-02f, - 3.33079047e-02f, 3.32199571e-02f, 3.31275989e-02f, 3.30309171e-02f, 3.29298707e-02f, 3.28245272e-02f, - 3.27148578e-02f, 3.26008736e-02f, 3.24826214e-02f, 3.23601088e-02f, 3.22333896e-02f, 3.21024170e-02f, - 3.19672441e-02f, 3.18278936e-02f, 3.16843345e-02f, 3.15366997e-02f, 3.13848799e-02f, 3.12290352e-02f, - 3.10690243e-02f, 3.09049916e-02f, 3.07369336e-02f, 3.05648689e-02f, 3.03888038e-02f, 3.02087717e-02f, - 3.00248441e-02f, 2.98369574e-02f, 2.96452432e-02f, 2.94496204e-02f, 2.92501866e-02f, 2.90469883e-02f, - 2.88399476e-02f, 2.86292114e-02f, 2.84147712e-02f, 2.81965942e-02f, 2.79748406e-02f, 2.77494197e-02f, - 2.75203789e-02f, 2.72878400e-02f, 2.70517095e-02f, 2.68121552e-02f, 2.65690870e-02f, 2.63226098e-02f, - 2.60726943e-02f, 2.58194963e-02f, 2.55629451e-02f, 2.53031010e-02f, 2.50399810e-02f, 2.47736597e-02f, - 2.45041477e-02f, 2.42315256e-02f, 2.39557468e-02f, 2.36769623e-02f, 2.33950736e-02f, 2.31102362e-02f, - 2.28224971e-02f, 2.25317031e-02f, 2.22381648e-02f, 2.19417110e-02f, 2.16425471e-02f, 2.13405133e-02f, - 2.10358896e-02f, 2.07284921e-02f, 2.04185680e-02f, 2.01059904e-02f, 1.97908336e-02f, 1.94732887e-02f, - 1.91531787e-02f, 1.88306966e-02f, 1.85058687e-02f, 1.81786392e-02f, 1.78491969e-02f, 1.75175015e-02f, - 1.71835867e-02f, 1.68475352e-02f, 1.65093898e-02f, 1.61692031e-02f, 1.58269655e-02f, 1.54827907e-02f, - 1.51366689e-02f, 1.47887139e-02f, 1.44389294e-02f, 1.40873427e-02f, 1.37340080e-02f, 1.33790326e-02f, - 1.30223932e-02f, 1.26641861e-02f, 1.23044226e-02f, 1.19431765e-02f, 1.15805002e-02f, 1.12164111e-02f, - 1.08509653e-02f, 1.04842481e-02f, 1.01162666e-02f, 9.74710167e-03f, 9.37680069e-03f, 9.00536466e-03f, - 8.63291194e-03f, 8.25939148e-03f, 7.88502432e-03f, 7.50968831e-03f, 7.13353252e-03f, 6.75659027e-03f, - 6.37882828e-03f, 6.00045997e-03f, 5.62135596e-03f, 5.24174543e-03f, 4.86153279e-03f, 4.48081380e-03f, - 4.09967626e-03f, 3.71809475e-03f, 3.33627494e-03f, 2.95406935e-03f, 2.57166556e-03f, 2.18903364e-03f, - 1.80628500e-03f, 1.42345007e-03f, 1.04058865e-03f, 6.57679498e-04f, 2.74863093e-04f, -1.07778511e-04f, - -4.90315566e-04f, -8.72652497e-04f, -1.25467925e-03f, -1.63644225e-03f, -2.01778445e-03f, -2.39873989e-03f, - -2.77921430e-03f, -3.15918926e-03f, -3.53860971e-03f, -3.91736471e-03f, -4.29549086e-03f, -4.67284699e-03f, - -5.04948106e-03f, -5.42528426e-03f, -5.80024768e-03f, -6.17427428e-03f, -6.54730878e-03f, -6.91938508e-03f, - -7.29034595e-03f, -7.66021378e-03f, -8.02892263e-03f, -8.39640912e-03f, -8.76266297e-03f, -9.12762869e-03f, - -9.49116781e-03f, -9.85334082e-03f, -1.02140743e-02f, -1.05733228e-02f, -1.09309952e-02f, -1.12870711e-02f, - -1.16415508e-02f, -1.19943548e-02f, -1.23453879e-02f, -1.26946677e-02f, -1.30421186e-02f, -1.33876714e-02f, - -1.37313784e-02f, -1.40730795e-02f, -1.44128056e-02f, -1.47504705e-02f, -1.50860541e-02f, -1.54194741e-02f, - -1.57507671e-02f, -1.60798371e-02f, -1.64066036e-02f, -1.67310604e-02f, -1.70531987e-02f, -1.73730001e-02f, - -1.76903078e-02f, -1.80051688e-02f, -1.83174077e-02f, -1.86272591e-02f, -1.89344070e-02f, -1.92389907e-02f, - -1.95408492e-02f, -1.98400318e-02f, -2.01364605e-02f, -2.04300668e-02f, -2.07208926e-02f, -2.10087937e-02f, - -2.12938652e-02f, -2.15759574e-02f, -2.18551013e-02f, -2.21312220e-02f, -2.24042745e-02f, -2.26742860e-02f, - -2.29411260e-02f, -2.32049148e-02f, -2.34654110e-02f, -2.37227721e-02f, -2.39768235e-02f, -2.42276411e-02f, - -2.44751379e-02f, -2.47192650e-02f, -2.49600362e-02f, -2.51974042e-02f, -2.54313027e-02f, -2.56617740e-02f, - -2.58887045e-02f, -2.61121477e-02f, -2.63320352e-02f, -2.65483312e-02f, -2.67610282e-02f, -2.69700587e-02f, - -2.71754890e-02f, -2.73771747e-02f, -2.75751739e-02f, -2.77694223e-02f, -2.79599024e-02f, -2.81466241e-02f, - -2.83295324e-02f, -2.85086104e-02f, -2.86838101e-02f, -2.88551421e-02f, -2.90225730e-02f, -2.91861382e-02f, - -2.93457015e-02f, -2.95013159e-02f, -2.96529712e-02f, -2.98006591e-02f, -2.99442609e-02f, -3.00838544e-02f, - -3.02194544e-02f, -3.03509511e-02f, -3.04783727e-02f, -3.06016907e-02f, -3.07209087e-02f, -3.08359939e-02f, - -3.09469923e-02f, -3.10537181e-02f, -3.11563858e-02f, -3.12548192e-02f, -3.13491069e-02f, -3.14392145e-02f, - -3.15250342e-02f, -3.16066824e-02f, -3.16841299e-02f, -3.17573137e-02f, -3.18262404e-02f, -3.18909536e-02f, - -3.19513220e-02f, -3.20075305e-02f, -3.20594355e-02f, -3.21070396e-02f, -3.21503911e-02f, -3.21893920e-02f, - -3.22242012e-02f, -3.22546669e-02f, -3.22808111e-02f, -3.23027225e-02f, -3.23202849e-02f, -3.23336268e-02f, - -3.23425693e-02f, -3.23473128e-02f, -3.23476967e-02f, -3.23437682e-02f, -3.23355960e-02f, -3.23230887e-02f, - -3.23063765e-02f, -3.22852975e-02f, -3.22599812e-02f, -3.22303702e-02f, -3.21965348e-02f, -3.21584077e-02f, - -3.21160173e-02f, -3.20693892e-02f, -3.20185361e-02f, -3.19634368e-02f, -3.19041214e-02f, -3.18406044e-02f, - -3.17728431e-02f, -3.17009390e-02f, -3.16248424e-02f, -3.15445476e-02f, -3.14600987e-02f, -3.13715950e-02f, - -3.12788396e-02f, -3.11820384e-02f, -3.10811146e-02f, -3.09760980e-02f, -3.08670573e-02f, -3.07538919e-02f, - -3.06367208e-02f, -3.05155461e-02f, -3.03903235e-02f, -3.02611659e-02f, -3.01279834e-02f, -2.99909203e-02f, - -2.98498714e-02f, -2.97049306e-02f, -2.95561195e-02f, -2.94034192e-02f, -2.92469522e-02f, -2.90865546e-02f, - -2.89224410e-02f, -2.87544577e-02f, -2.85827721e-02f, -2.84074153e-02f, -2.82282824e-02f, -2.80455226e-02f, - -2.78590542e-02f, -2.76690314e-02f, -2.74753455e-02f, -2.72781449e-02f, -2.70773086e-02f, -2.68730387e-02f, - -2.66652496e-02f, -2.64540223e-02f, -2.62393516e-02f, -2.60212726e-02f, -2.57998524e-02f, -2.55750507e-02f, - -2.53469882e-02f, -2.51156115e-02f, -2.48810271e-02f, -2.46431933e-02f, -2.44022342e-02f, -2.41580427e-02f, - -2.39108161e-02f, -2.36604867e-02f, -2.34071512e-02f, -2.31507016e-02f, -2.28913408e-02f, -2.26291070e-02f, - -2.23639074e-02f, -2.20958441e-02f, -2.18249604e-02f, -2.15512656e-02f, -2.12748409e-02f, -2.09956975e-02f, - -2.07138702e-02f, -2.04293886e-02f, -2.01423837e-02f, -1.98526889e-02f, -1.95605809e-02f, -1.92659307e-02f, - -1.89688519e-02f, -1.86693537e-02f, -1.83675478e-02f, -1.80634048e-02f, -1.77569645e-02f, -1.74483030e-02f, - -1.71374083e-02f, -1.68243860e-02f, -1.65092639e-02f, -1.61920625e-02f, -1.58728348e-02f, -1.55516240e-02f, - -1.52285038e-02f, -1.49034484e-02f, -1.45765539e-02f, -1.42478607e-02f, -1.39173801e-02f, -1.35852272e-02f, - -1.32514015e-02f, -1.29158872e-02f, -1.25788214e-02f, -1.22402284e-02f, -1.19001423e-02f, -1.15586179e-02f, - -1.12156755e-02f, -1.08713760e-02f, -1.05257774e-02f, -1.01789266e-02f, -9.83085397e-03f, -9.48162029e-03f, - -9.13125709e-03f, -8.77976936e-03f, -8.42738038e-03f, -8.07388688e-03f, -7.71950986e-03f, -7.36427489e-03f, - -7.00816333e-03f, -6.65127659e-03f, -6.29360914e-03f, -5.93533327e-03f, -5.57632200e-03f, -5.21679333e-03f, - -4.85663924e-03f, -4.49604009e-03f, -4.13493798e-03f, -3.77345470e-03f, -3.41163402e-03f, -3.04946314e-03f, - -2.68705111e-03f, -2.32442109e-03f, -1.96164526e-03f, -1.59872250e-03f, -1.23573747e-03f, -8.72717884e-04f, - -5.09786140e-04f, -1.46905871e-04f, 2.15867789e-04f, 5.78506084e-04f, 9.40845074e-04f, 1.30298103e-03f, - 1.66472268e-03f, 2.02621176e-03f, 2.38719238e-03f, 2.74777117e-03f, 3.10779422e-03f, 3.46727046e-03f, - 3.82620397e-03f, 4.18439232e-03f, 4.54196274e-03f, 4.89876682e-03f, 5.25473839e-03f, 5.60990584e-03f, - 5.96418427e-03f, 6.31751957e-03f, 6.66987957e-03f, 7.02121363e-03f, 7.37150400e-03f, 7.72061635e-03f, - 8.06865174e-03f, 8.41538852e-03f, 8.76090150e-03f, 9.10511260e-03f, 9.44797144e-03f, 9.78948992e-03f, - 1.01295028e-02f, 1.04680839e-02f, 1.08050665e-02f, 1.11405639e-02f, 1.14744388e-02f, 1.18066204e-02f, - 1.21371309e-02f, 1.24658528e-02f, 1.27928143e-02f, 1.31179522e-02f, 1.34412056e-02f, 1.37625537e-02f, - 1.40819526e-02f, 1.43993697e-02f, 1.47147324e-02f, 1.50279495e-02f, 1.53391349e-02f, 1.56481075e-02f, - 1.59548993e-02f, 1.62594474e-02f, 1.65617273e-02f, 1.68616687e-02f, 1.71592662e-02f, 1.74544156e-02f, - 1.77471683e-02f, 1.80374563e-02f, 1.83252044e-02f, 1.86104249e-02f, 1.88930441e-02f, 1.91730490e-02f, - 1.94504342e-02f, 1.97250325e-02f, 1.99969983e-02f, 2.02661305e-02f, 2.05324764e-02f, 2.07959856e-02f, - 2.10566511e-02f, 2.13143623e-02f, 2.15691938e-02f, 2.18210728e-02f, 2.20698957e-02f, 2.23157133e-02f, - 2.25584582e-02f, 2.27981174e-02f, 2.30346314e-02f, 2.32680691e-02f, 2.34982050e-02f, 2.37252032e-02f, - 2.39489319e-02f, 2.41694013e-02f, 2.43865384e-02f, 2.46003950e-02f, 2.48108711e-02f, 2.50179646e-02f, - 2.52216517e-02f, 2.54219153e-02f, 2.56187001e-02f, 2.58120292e-02f, 2.60018390e-02f, 2.61881303e-02f, - 2.63708419e-02f, 2.65499967e-02f, 2.67255374e-02f, 2.68974448e-02f, 2.70657402e-02f, 2.72303466e-02f, - 2.73913193e-02f, 2.75484874e-02f, 2.77020219e-02f, 2.78517821e-02f, 2.79977893e-02f, 2.81399887e-02f, - 2.82784002e-02f, 2.84130143e-02f, 2.85438031e-02f, 2.86707477e-02f, 2.87938057e-02f, 2.89129871e-02f, - 2.90283017e-02f, 2.91397328e-02f, 2.92471920e-02f, 2.93507561e-02f, 2.94503527e-02f, 2.95459902e-02f, - 2.96376892e-02f, 2.97254018e-02f, 2.98091628e-02f, 2.98888753e-02f, 2.99646120e-02f, 3.00363054e-02f, - 3.01040251e-02f, 3.01676383e-02f, 3.02273144e-02f, 3.02828951e-02f, 3.03344640e-02f, 3.03818962e-02f, - 3.04253239e-02f, 3.04647288e-02f, 3.05000049e-02f, 3.05312696e-02f, 3.05583942e-02f, 3.05815705e-02f, - 3.06004894e-02f, 3.06154460e-02f, 3.06263430e-02f, 3.06331108e-02f, 3.06358465e-02f, 3.06344788e-02f, - 3.06290193e-02f, 3.06195822e-02f, 3.06059489e-02f, 3.05883543e-02f, 3.05666214e-02f, 3.05409258e-02f, - 3.05111245e-02f, 3.04772806e-02f, 3.04393993e-02f, 3.03975191e-02f, 3.03515632e-02f, 3.03016128e-02f, - 3.02476554e-02f, 3.01897017e-02f, 3.01277345e-02f, 3.00618240e-02f, 2.99919027e-02f, 2.99180773e-02f, - 2.98402490e-02f, 2.97585174e-02f, 2.96728574e-02f, 2.95832797e-02f, 2.94898382e-02f, 2.93924078e-02f, - 2.92912461e-02f, 2.91861219e-02f, 2.90772581e-02f, 2.89644674e-02f, 2.88479417e-02f, 2.87276124e-02f, - 2.86034621e-02f, 2.84756561e-02f, 2.83440123e-02f, 2.82087566e-02f, 2.80697176e-02f, 2.79270487e-02f, - 2.77807113e-02f, 2.76307089e-02f, 2.74771638e-02f, 2.73199514e-02f, 2.71592541e-02f, 2.69948930e-02f, - 2.68271166e-02f, 2.66557588e-02f, 2.64809878e-02f, 2.63027242e-02f, 2.61210693e-02f, 2.59359715e-02f, - 2.57475530e-02f, 2.55557522e-02f, 2.53606398e-02f, 2.51622086e-02f, 2.49605440e-02f, 2.47556716e-02f, - 2.45474703e-02f, 2.43362031e-02f, 2.41217436e-02f, 2.39041604e-02f, 2.36834884e-02f, 2.34597488e-02f, - 2.32330179e-02f, 2.30032438e-02f, 2.27705337e-02f, 2.25348356e-02f, 2.22962698e-02f, 2.20548810e-02f, - 2.18105968e-02f, 2.15635197e-02f, 2.13136513e-02f, 2.10611203e-02f, 2.08058638e-02f, 2.05478820e-02f, - 2.02873365e-02f, 2.00241854e-02f, 1.97584339e-02f, 1.94902307e-02f, 1.92194805e-02f, 1.89463298e-02f, - 1.86707266e-02f, 1.83928079e-02f, 1.81125018e-02f, 1.78299682e-02f, 1.75450495e-02f, 1.72580464e-02f, - 1.69687461e-02f, 1.66774353e-02f, 1.63838782e-02f, 1.60883842e-02f, 1.57908042e-02f, 1.54912847e-02f, - 1.51898029e-02f, 1.48864009e-02f, 1.45811540e-02f, 1.42740737e-02f, 1.39653065e-02f, 1.36546833e-02f, - 1.33424611e-02f, 1.30285360e-02f, 1.27130260e-02f, 1.23959356e-02f, 1.20773688e-02f, 1.17572560e-02f, - 1.14357644e-02f, 1.11128197e-02f, 1.07885921e-02f, 1.04630167e-02f, 1.01362614e-02f, 9.80817990e-03f, - 9.47899536e-03f, 9.14861756e-03f, 8.81722271e-03f, 8.48474640e-03f, 8.15130098e-03f, 7.81689076e-03f, - 7.48158610e-03f, 7.14541247e-03f, 6.80843658e-03f, 6.47066701e-03f, 6.13217650e-03f, 5.79303958e-03f, - 5.45320459e-03f, 5.11287351e-03f, 4.77193492e-03f, 4.43045643e-03f, 4.08862588e-03f, 3.74633390e-03f, - 3.40369720e-03f, 3.06073233e-03f, 2.71751426e-03f, 2.37402477e-03f, 2.03043569e-03f, 1.68664144e-03f, - 1.34277669e-03f, 9.98944824e-04f, 6.55037894e-04f, 3.11216088e-04f, -3.25344123e-05f, -3.76121734e-04f, - -7.19514448e-04f, -1.06269513e-03f, -1.40555104e-03f, -1.74812822e-03f, -2.09037476e-03f, -2.43210782e-03f, - -2.77345843e-03f, -3.11424578e-03f, -3.45452055e-03f, -3.79415569e-03f, -4.13321868e-03f, -4.47149900e-03f, - -4.80912931e-03f, -5.14598217e-03f, -5.48196215e-03f, -5.81713902e-03f, -6.15134490e-03f, -6.48460396e-03f, - -6.81691549e-03f, -7.14816822e-03f, -7.47833891e-03f, -7.80736704e-03f, -8.13519183e-03f, -8.46188491e-03f, - -8.78724638e-03f, -9.11135016e-03f, -9.43406575e-03f, -9.75544960e-03f, -1.00753630e-02f, -1.03938753e-02f, - -1.07108316e-02f, -1.10261641e-02f, -1.13400153e-02f, -1.16521814e-02f, -1.19626752e-02f, -1.22714474e-02f, - -1.25784529e-02f, -1.28836955e-02f, -1.31870898e-02f, -1.34886258e-02f, -1.37881925e-02f, -1.40858077e-02f, - -1.43814669e-02f, -1.46750518e-02f, -1.49666443e-02f, -1.52560439e-02f, -1.55433576e-02f, -1.58284542e-02f, - -1.61113097e-02f, -1.63919220e-02f, -1.66702649e-02f, -1.69462815e-02f, -1.72198792e-02f, -1.74911402e-02f, - -1.77599229e-02f, -1.80262371e-02f, -1.82900432e-02f, -1.85513378e-02f, -1.88100366e-02f, -1.90661205e-02f, - -1.93196092e-02f, -1.95703584e-02f, -1.98184278e-02f, -2.00637588e-02f, -2.03063517e-02f, -2.05461221e-02f, - -2.07830331e-02f, -2.10171401e-02f, -2.12482997e-02f, -2.14765593e-02f, -2.17019129e-02f, -2.19242464e-02f, - -2.21435548e-02f, -2.23598565e-02f, -2.25730818e-02f, -2.27832069e-02f, -2.29902452e-02f, -2.31941398e-02f, - -2.33948425e-02f, -2.35923631e-02f, -2.37866659e-02f, -2.39777322e-02f, -2.41654916e-02f, -2.43499980e-02f, - -2.45311580e-02f, -2.47090181e-02f, -2.48835042e-02f, -2.50546132e-02f, -2.52222965e-02f, -2.53865678e-02f, - -2.55473914e-02f, -2.57047733e-02f, -2.58586341e-02f, -2.60090280e-02f, -2.61558607e-02f, -2.62991947e-02f, - -2.64389339e-02f, -2.65751234e-02f, -2.67077004e-02f, -2.68366809e-02f, -2.69620222e-02f, -2.70837742e-02f, - -2.72018148e-02f, -2.73162192e-02f, -2.74269208e-02f, -2.75339187e-02f, -2.76372852e-02f, -2.77368278e-02f, - -2.78327395e-02f, -2.79247981e-02f, -2.80131822e-02f, -2.80977744e-02f, -2.81785940e-02f, -2.82556646e-02f, - -2.83289030e-02f, -2.83983523e-02f, -2.84639727e-02f, -2.85257936e-02f, -2.85838320e-02f, -2.86379610e-02f, - -2.86883499e-02f, -2.87348176e-02f, -2.87775405e-02f, -2.88162861e-02f, -2.88512718e-02f, -2.88823617e-02f, - -2.89096369e-02f, -2.89330514e-02f, -2.89525386e-02f, -2.89682453e-02f, -2.89800243e-02f, -2.89879789e-02f, - -2.89920524e-02f, -2.89922710e-02f, -2.89886417e-02f, -2.89811944e-02f, -2.89697791e-02f, -2.89546235e-02f, - -2.89355202e-02f, -2.89126914e-02f, -2.88859435e-02f, -2.88553996e-02f, -2.88210018e-02f, -2.87827416e-02f, - -2.87407485e-02f, -2.86949050e-02f, -2.86452716e-02f, -2.85918111e-02f, -2.85345925e-02f, -2.84736219e-02f, - -2.84088482e-02f, -2.83403326e-02f, -2.82680946e-02f, -2.81920915e-02f, -2.81123777e-02f, -2.80289295e-02f, - -2.79418309e-02f, -2.78510071e-02f, -2.77565594e-02f, -2.76584150e-02f, -2.75566461e-02f, -2.74512520e-02f, - -2.73422024e-02f, -2.72296019e-02f, -2.71134122e-02f, -2.69936746e-02f, -2.68703567e-02f, -2.67435816e-02f, - -2.66132164e-02f, -2.64793986e-02f, -2.63421179e-02f, -2.62013669e-02f, -2.60571701e-02f, -2.59095978e-02f, - -2.57586169e-02f, -2.56042740e-02f, -2.54466065e-02f, -2.52855859e-02f, -2.51212794e-02f, -2.49536914e-02f, - -2.47828359e-02f, -2.46087653e-02f, -2.44315005e-02f, -2.42510272e-02f, -2.40674162e-02f, -2.38806374e-02f, - -2.36908324e-02f, -2.34978733e-02f, -2.33019387e-02f, -2.31028844e-02f, -2.29009427e-02f, -2.26959408e-02f, - -2.24880789e-02f, -2.22772503e-02f, -2.20635644e-02f, -2.18470212e-02f, -2.16276745e-02f, -2.14055110e-02f, - -2.11806041e-02f, -2.09529864e-02f, -2.07226208e-02f, -2.04896448e-02f, -2.02539781e-02f, -2.00157950e-02f, - -1.97749374e-02f, -1.95316410e-02f, -1.92857376e-02f, -1.90374848e-02f, -1.87867574e-02f, -1.85336125e-02f, - -1.82781046e-02f, -1.80202275e-02f, -1.77601279e-02f, -1.74977216e-02f, -1.72331424e-02f, -1.69663385e-02f, - -1.66973487e-02f, -1.64263329e-02f, -1.61531722e-02f, -1.58779964e-02f, -1.56008103e-02f, -1.53216796e-02f, - -1.50406006e-02f, -1.47576481e-02f, -1.44728443e-02f, -1.41862196e-02f, -1.38978180e-02f, -1.36077044e-02f, - -1.33158618e-02f, -1.30223814e-02f, -1.27273243e-02f, -1.24306379e-02f, -1.21324291e-02f, -1.18327457e-02f, - -1.15316212e-02f, -1.12290352e-02f, -1.09251282e-02f, -1.06198838e-02f, -1.03133128e-02f, -1.00054941e-02f, - -9.69649301e-03f, -9.38635755e-03f, -9.07504565e-03f, -8.76265043e-03f, -8.44926686e-03f, -8.13482122e-03f, - -7.81948742e-03f, -7.50317946e-03f, -7.18602618e-03f, -6.86805294e-03f, -6.54932071e-03f, -6.22976826e-03f, - -5.90957429e-03f, -5.58870069e-03f, -5.26725148e-03f, -4.94521331e-03f, -4.62263839e-03f, -4.29957995e-03f, - -3.97609354e-03f, -3.65216614e-03f, -3.32795841e-03f, -3.00336232e-03f, -2.67854820e-03f, -2.35352096e-03f, - -2.02825840e-03f, -1.70289546e-03f, -1.37744319e-03f, -1.05193825e-03f, -7.26411916e-04f, -4.00922657e-04f, - -7.55011306e-05f, 2.49749536e-04f, 5.74874111e-04f, 8.99779387e-04f, 1.22443339e-03f, 1.54879620e-03f, - 1.87279893e-03f, 2.19644302e-03f, 2.51968615e-03f, 2.84238329e-03f, 3.16465185e-03f, 3.48629869e-03f, - 3.80739937e-03f, 4.12784333e-03f, 4.44762793e-03f, 4.76663127e-03f, 5.08492533e-03f, 5.40238743e-03f, - 5.71906418e-03f, 6.03471726e-03f, 6.34955625e-03f, 6.66336254e-03f, 6.97617902e-03f, 7.28790264e-03f, - 7.59857732e-03f, 7.90806830e-03f, 8.21639008e-03f, 8.52355893e-03f, 8.82935417e-03f, 9.13391594e-03f, - 9.43710165e-03f, 9.73896732e-03f, 1.00393663e-02f, 1.03383169e-02f, 1.06357421e-02f, 1.09316362e-02f, - 1.12259720e-02f, 1.15186941e-02f, 1.18097636e-02f, 1.20991004e-02f, 1.23867529e-02f, 1.26726230e-02f, - 1.29566977e-02f, 1.32389094e-02f, 1.35192402e-02f, 1.37976786e-02f, 1.40741474e-02f, 1.43486447e-02f, - 1.46211000e-02f, 1.48915238e-02f, 1.51598101e-02f, 1.54260114e-02f, 1.56899888e-02f, 1.59518320e-02f, - 1.62113924e-02f, 1.64687417e-02f, 1.67237226e-02f, 1.69764445e-02f, 1.72267516e-02f, 1.74746909e-02f, - 1.77201570e-02f, 1.79632437e-02f, 1.82037449e-02f, 1.84417968e-02f, 1.86772024e-02f, 1.89100900e-02f, - 1.91403720e-02f, 1.93679863e-02f, 1.95929573e-02f, 1.98151690e-02f, 2.00346761e-02f, 2.02514472e-02f, - 2.04654294e-02f, 2.06765126e-02f, 2.08848869e-02f, 2.10903141e-02f, 2.12928448e-02f, 2.14924666e-02f, - 2.16892008e-02f, 2.18828690e-02f, 2.20736187e-02f, 2.22612996e-02f, 2.24459584e-02f, 2.26275262e-02f, - 2.28060566e-02f, 2.29814115e-02f, 2.31536837e-02f, 2.33227877e-02f, 2.34887190e-02f, 2.36514323e-02f, - 2.38109436e-02f, 2.39671785e-02f, 2.41202512e-02f, 2.42699470e-02f, 2.44163577e-02f, 2.45595080e-02f, - 2.46993289e-02f, 2.48357871e-02f, 2.49688625e-02f, 2.50985418e-02f, 2.52248167e-02f, 2.53477317e-02f, - 2.54672105e-02f, 2.55831881e-02f, 2.56957823e-02f, 2.58048817e-02f, 2.59104857e-02f, 2.60125829e-02f, - 2.61111853e-02f, 2.62063199e-02f, 2.62978564e-02f, 2.63858501e-02f, 2.64702911e-02f, 2.65512224e-02f, - 2.66285717e-02f, 2.67023289e-02f, 2.67724460e-02f, 2.68390087e-02f, 2.69019685e-02f, 2.69613355e-02f, - 2.70170878e-02f, 2.70691757e-02f, 2.71176480e-02f, 2.71625201e-02f, 2.72037070e-02f, 2.72412685e-02f, - 2.72752329e-02f, 2.73054933e-02f, 2.73320941e-02f, 2.73550782e-02f, 2.73743561e-02f, 2.73900682e-02f, - 2.74020613e-02f, 2.74103862e-02f, 2.74151183e-02f, 2.74161290e-02f, 2.74135251e-02f, 2.74072238e-02f, - 2.73973292e-02f, 2.73837472e-02f, 2.73665538e-02f, 2.73456852e-02f, 2.73212134e-02f, 2.72930710e-02f, - 2.72613578e-02f, 2.72259760e-02f, 2.71870523e-02f, 2.71443869e-02f, 2.70982818e-02f, 2.70484869e-02f, - 2.69951061e-02f, 2.69381884e-02f, 2.68776754e-02f, 2.68136122e-02f, 2.67460330e-02f, 2.66748853e-02f, - 2.66002235e-02f, 2.65220088e-02f, 2.64403614e-02f, 2.63551691e-02f, 2.62665101e-02f, 2.61744152e-02f, - 2.60788656e-02f, 2.59798768e-02f, 2.58774032e-02f, 2.57715998e-02f, 2.56623637e-02f, 2.55497978e-02f, - 2.54338210e-02f, 2.53145447e-02f, 2.51919050e-02f, 2.50659935e-02f, 2.49367443e-02f, 2.48042859e-02f, - 2.46685457e-02f, 2.45295889e-02f, 2.43873873e-02f, 2.42420323e-02f, 2.40934750e-02f, 2.39417973e-02f, - 2.37869612e-02f, 2.36290451e-02f, 2.34680288e-02f, 2.33039516e-02f, 2.31368801e-02f, 2.29667053e-02f, - 2.27936073e-02f, 2.26174955e-02f, 2.24384956e-02f, 2.22565460e-02f, 2.20717245e-02f, 2.18840121e-02f, - 2.16934530e-02f, 2.15001321e-02f, 2.13040129e-02f, 2.11051196e-02f, 2.09034711e-02f, 2.06991107e-02f, - 2.04921423e-02f, 2.02824915e-02f, 2.00702468e-02f, 1.98553494e-02f, 1.96379643e-02f, 1.94180101e-02f, - 1.91955758e-02f, 1.89707181e-02f, 1.87433250e-02f, 1.85136176e-02f, 1.82814658e-02f, 1.80470272e-02f, - 1.78102834e-02f, 1.75711872e-02f, 1.73299647e-02f, 1.70864377e-02f, 1.68407848e-02f, 1.65929488e-02f, - 1.63430476e-02f, 1.60910252e-02f, 1.58370010e-02f, 1.55809661e-02f, 1.53229095e-02f, 1.50629772e-02f, - 1.48011456e-02f, 1.45374391e-02f, 1.42718435e-02f, 1.40045467e-02f, 1.37354594e-02f, 1.34646080e-02f, - 1.31921457e-02f, 1.29179760e-02f, 1.26422504e-02f, 1.23649202e-02f, 1.20860530e-02f, 1.18057153e-02f, - 1.15239092e-02f, 1.12406933e-02f, 1.09560695e-02f, 1.06701206e-02f, 1.03828407e-02f, 1.00943366e-02f, - 9.80459818e-03f, 9.51368208e-03f, 9.22161254e-03f, 8.92838244e-03f, 8.63413774e-03f, 8.33885014e-03f, - 8.04256985e-03f, 7.74535291e-03f, 7.44722334e-03f, 7.14822557e-03f, 6.84839540e-03f, 6.54774405e-03f, - 6.24638280e-03f, 5.94435540e-03f, 5.64158321e-03f, 5.33821860e-03f, 5.03421560e-03f, 4.72974128e-03f, - 4.42473401e-03f, 4.11928700e-03f, 3.81336181e-03f, 3.50711037e-03f, 3.20051230e-03f, 2.89358682e-03f, - 2.58643490e-03f, 2.27902715e-03f, 1.97147268e-03f, 1.66376846e-03f, 1.35596570e-03f, 1.04814444e-03f, - 7.40277782e-04f, 4.32445803e-04f, 1.24693631e-04f, -1.82960881e-04f, -4.90450155e-04f, -7.97757014e-04f, - -1.10483316e-03f, -1.41160373e-03f, -1.71809242e-03f, -2.02419366e-03f, -2.32992880e-03f, -2.63518600e-03f, - -2.93999618e-03f, -3.24431975e-03f, -3.54803569e-03f, -3.85120398e-03f, -4.15362259e-03f, -4.45548653e-03f, - -4.75655433e-03f, -5.05685618e-03f, -5.35640830e-03f, -5.65508385e-03f, -5.95294778e-03f, -6.24982839e-03f, - -6.54574061e-03f, -6.84068982e-03f, -7.13462996e-03f, -7.42742506e-03f, -7.71916803e-03f, -8.00971073e-03f, - -8.29910958e-03f, -8.58730134e-03f, -8.87416105e-03f, -9.15971122e-03f, -9.44400899e-03f, -9.72687017e-03f, - -1.00083465e-02f, -1.02883317e-02f, -1.05668255e-02f, -1.08438239e-02f, -1.11192286e-02f, -1.13931174e-02f, - -1.16652657e-02f, -1.19358024e-02f, -1.22046160e-02f, -1.24717168e-02f, -1.27370269e-02f, -1.30005027e-02f, - -1.32621961e-02f, -1.35219747e-02f, -1.37798185e-02f, -1.40357712e-02f, -1.42896729e-02f, -1.45416329e-02f, - -1.47915213e-02f, -1.50393037e-02f, -1.52850223e-02f, -1.55286285e-02f, -1.57699607e-02f, -1.60091186e-02f, - -1.62461094e-02f, -1.64808101e-02f, -1.67131958e-02f, -1.69432687e-02f, -1.71709348e-02f, -1.73962590e-02f, - -1.76191975e-02f, -1.78396322e-02f, -1.80576576e-02f, -1.82731629e-02f, -1.84861015e-02f, -1.86965133e-02f, - -1.89043639e-02f, -1.91095860e-02f, -1.93121584e-02f, -1.95120971e-02f, -1.97093402e-02f, -1.99038927e-02f, - -2.00956557e-02f, -2.02847233e-02f, -2.04709679e-02f, -2.06544055e-02f, -2.08350144e-02f, -2.10127943e-02f, - -2.11876233e-02f, -2.13596582e-02f, -2.15287096e-02f, -2.16948075e-02f, -2.18580147e-02f, -2.20181299e-02f, - -2.21753478e-02f, -2.23294786e-02f, -2.24805666e-02f, -2.26285974e-02f, -2.27735862e-02f, -2.29154850e-02f, - -2.30542040e-02f, -2.31898011e-02f, -2.33222896e-02f, -2.34515585e-02f, -2.35776689e-02f, -2.37006256e-02f, - -2.38203190e-02f, -2.39368029e-02f, -2.40500651e-02f, -2.41600318e-02f, -2.42667403e-02f, -2.43701567e-02f, - -2.44703330e-02f, -2.45671312e-02f, -2.46606659e-02f, -2.47508475e-02f, -2.48376812e-02f, -2.49211943e-02f, - -2.50013050e-02f, -2.50781249e-02f, -2.51515212e-02f, -2.52215059e-02f, -2.52881185e-02f, -2.53513363e-02f, - -2.54111401e-02f, -2.54675470e-02f, -2.55204847e-02f, -2.55700324e-02f, -2.56161581e-02f, -2.56588492e-02f, - -2.56980303e-02f, -2.57338568e-02f, -2.57661666e-02f, -2.57951143e-02f, -2.58205264e-02f, -2.58425337e-02f, - -2.58609966e-02f, -2.58761325e-02f, -2.58877299e-02f, -2.58958386e-02f, -2.59005997e-02f, -2.59017996e-02f, - -2.58995900e-02f, -2.58939059e-02f, -2.58847565e-02f, -2.58722100e-02f, -2.58562037e-02f, -2.58367372e-02f, - -2.58138559e-02f, -2.57874864e-02f, -2.57577418e-02f, -2.57245268e-02f, -2.56879569e-02f, -2.56479277e-02f, - -2.56045146e-02f, -2.55576664e-02f, -2.55074820e-02f, -2.54538651e-02f, -2.53969391e-02f, -2.53365874e-02f, - -2.52728977e-02f, -2.52058757e-02f, -2.51355259e-02f, -2.50618439e-02f, -2.49848094e-02f, -2.49045343e-02f, - -2.48209406e-02f, -2.47340938e-02f, -2.46439188e-02f, -2.45505582e-02f, -2.44539349e-02f, -2.43541263e-02f, - -2.42510482e-02f, -2.41448335e-02f, -2.40354287e-02f, -2.39228456e-02f, -2.38071298e-02f, -2.36882836e-02f, - -2.35663093e-02f, -2.34412734e-02f, -2.33131340e-02f, -2.31819550e-02f, -2.30477413e-02f, -2.29105112e-02f, - -2.27702550e-02f, -2.26270602e-02f, -2.24808915e-02f, -2.23317637e-02f, -2.21797262e-02f, -2.20248260e-02f, - -2.18669984e-02f, -2.17063709e-02f, -2.15428904e-02f, -2.13765821e-02f, -2.12075405e-02f, -2.10356977e-02f, - -2.08611556e-02f, -2.06838618e-02f, -2.05039124e-02f, -2.03213103e-02f, -2.01360589e-02f, -1.99482272e-02f, - -1.97577610e-02f, -1.95647611e-02f, -1.93692174e-02f, -1.91712304e-02f, -1.89706599e-02f, -1.87677835e-02f, - -1.85623642e-02f, -1.83546602e-02f, -1.81444575e-02f, -1.79320481e-02f, -1.77173331e-02f, -1.75002524e-02f, - -1.72809905e-02f, -1.70595012e-02f, -1.68358455e-02f, -1.66099822e-02f, -1.63820630e-02f, -1.61520022e-02f, - -1.59199362e-02f, -1.56858259e-02f, -1.54497064e-02f, -1.52116044e-02f, -1.49716179e-02f, -1.47297301e-02f, - -1.44859507e-02f, -1.42403485e-02f, -1.39929501e-02f, -1.37438164e-02f, -1.34929271e-02f, -1.32403416e-02f, - -1.29860610e-02f, -1.27302401e-02f, -1.24727734e-02f, -1.22137605e-02f, -1.19532368e-02f, -1.16912319e-02f, - -1.14277289e-02f, -1.11628490e-02f, -1.08966077e-02f, -1.06290102e-02f, -1.03600911e-02f, -1.00899436e-02f, - -9.81847806e-03f, -9.54588736e-03f, -9.27212473e-03f, -8.99726198e-03f, -8.72126634e-03f, -8.44427195e-03f, - -8.16626344e-03f, -7.88721209e-03f, -7.60730642e-03f, -7.32644527e-03f, -7.04479695e-03f, -6.76228386e-03f, - -6.47897028e-03f, -6.19492062e-03f, -5.91017737e-03f, -5.62474915e-03f, -5.33874807e-03f, -5.05208150e-03f, - -4.76489278e-03f, -4.47720300e-03f, -4.18899033e-03f, -3.90038080e-03f, -3.61138283e-03f, -3.32197386e-03f, - -3.03231354e-03f, -2.74232933e-03f, -2.45208890e-03f, -2.16164931e-03f, -1.87106692e-03f, -1.58034470e-03f, - -1.28955414e-03f, -9.98688338e-04f, -7.07813882e-04f, -4.16979313e-04f, -1.26185272e-04f, 1.64456925e-04f, - 4.55003095e-04f, 7.45331032e-04f, 1.03542217e-03f, 1.32530295e-03f, 1.61484083e-03f, 1.90406763e-03f, - 2.19290092e-03f, 2.48134750e-03f, 2.76928828e-03f, 3.05678721e-03f, 3.34374519e-03f, 3.63012307e-03f, - 3.91590771e-03f, 4.20102979e-03f, 4.48546635e-03f, 4.76923821e-03f, 5.05218214e-03f, 5.33439553e-03f, - 5.61573881e-03f, 5.89621986e-03f, 6.17578819e-03f, 6.45440950e-03f, 6.73207025e-03f, 7.00871726e-03f, - 7.28431592e-03f, 7.55880110e-03f, 7.83217156e-03f, 8.10437253e-03f, 8.37538102e-03f, 8.64517968e-03f, - 8.91370898e-03f, 9.18085855e-03f, 9.44678279e-03f, 9.71124324e-03f, 9.97435385e-03f, 1.02359848e-02f, - 1.04961787e-02f, 1.07548125e-02f, 1.10119138e-02f, 1.12674588e-02f, 1.15213845e-02f, 1.17736465e-02f, - 1.20242368e-02f, 1.22731147e-02f, 1.25202901e-02f, 1.27656370e-02f, 1.30091887e-02f, 1.32508999e-02f, - 1.34907140e-02f, 1.37287257e-02f, 1.39646947e-02f, 1.41987141e-02f, 1.44308006e-02f, 1.46608068e-02f, - 1.48887869e-02f, 1.51146770e-02f, 1.53384557e-02f, 1.55600723e-02f, 1.57795297e-02f, 1.59967482e-02f, - 1.62118245e-02f, 1.64245750e-02f, 1.66350837e-02f, 1.68432400e-02f, 1.70491138e-02f, 1.72525781e-02f, - 1.74536778e-02f, 1.76523826e-02f, 1.78485706e-02f, 1.80423718e-02f, 1.82336353e-02f, 1.84224022e-02f, - 1.86086192e-02f, 1.87922776e-02f, 1.89733510e-02f, 1.91518289e-02f, 1.93276291e-02f, 1.95008417e-02f, - 1.96713016e-02f, 1.98391103e-02f, 2.00041977e-02f, 2.01665500e-02f, 2.03261236e-02f, 2.04829265e-02f, - 2.06368983e-02f, 2.07880462e-02f, 2.09364422e-02f, 2.10819081e-02f, 2.12244851e-02f, 2.13641738e-02f, - 2.15009522e-02f, 2.16348588e-02f, 2.17657633e-02f, 2.18937530e-02f, 2.20187230e-02f, 2.21407082e-02f, - 2.22596969e-02f, 2.23756289e-02f, 2.24885398e-02f, 2.25984139e-02f, 2.27052375e-02f, 2.28089433e-02f, - 2.29095691e-02f, 2.30071633e-02f, 2.31015205e-02f, 2.31928656e-02f, 2.32810315e-02f, 2.33660725e-02f, - 2.34478798e-02f, 2.35266093e-02f, 2.36020961e-02f, 2.36744877e-02f, 2.37435821e-02f, 2.38095806e-02f, - 2.38722559e-02f, 2.39317954e-02f, 2.39881230e-02f, 2.40412152e-02f, 2.40910498e-02f, 2.41376581e-02f, - 2.41810448e-02f, 2.42211280e-02f, 2.42580194e-02f, 2.42915871e-02f, 2.43219681e-02f, 2.43490649e-02f, - 2.43728712e-02f, 2.43934661e-02f, 2.44107582e-02f, 2.44247826e-02f, 2.44355716e-02f, 2.44430562e-02f, - 2.44472838e-02f, 2.44482735e-02f, 2.44459684e-02f, 2.44404026e-02f, 2.44315436e-02f, 2.44194737e-02f, - 2.44041269e-02f, 2.43855858e-02f, 2.43637186e-02f, 2.43386442e-02f, 2.43103477e-02f, 2.42787507e-02f, - 2.42439589e-02f, 2.42059758e-02f, 2.41647598e-02f, 2.41203219e-02f, 2.40726625e-02f, 2.40218820e-02f, - 2.39678009e-02f, 2.39106734e-02f, 2.38503317e-02f, 2.37867558e-02f, 2.37201036e-02f, 2.36502721e-02f, - 2.35773841e-02f, 2.35013061e-02f, 2.34221778e-02f, 2.33399028e-02f, 2.32545510e-02f, 2.31661547e-02f, - 2.30747049e-02f, 2.29802102e-02f, 2.28826822e-02f, 2.27821097e-02f, 2.26786184e-02f, 2.25720655e-02f, - 2.24625663e-02f, 2.23501106e-02f, 2.22347575e-02f, 2.21164281e-02f, 2.19952233e-02f, 2.18711044e-02f, - 2.17441824e-02f, 2.16143599e-02f, 2.14817096e-02f, 2.13462590e-02f, 2.12080092e-02f, 2.10670191e-02f, - 2.09232143e-02f, 2.07767456e-02f, 2.06274943e-02f, 2.04755923e-02f, 2.03210249e-02f, 2.01638005e-02f, - 2.00039487e-02f, 1.98415128e-02f, 1.96764225e-02f, 1.95088527e-02f, 1.93387658e-02f, 1.91660785e-02f, - 1.89910124e-02f, 1.88133966e-02f, 1.86334211e-02f, 1.84509496e-02f, 1.82661611e-02f, 1.80789582e-02f, - 1.78894734e-02f, 1.76976425e-02f, 1.75035512e-02f, 1.73072091e-02f, 1.71086166e-02f, 1.69078613e-02f, - 1.67048497e-02f, 1.64997769e-02f, 1.62925955e-02f, 1.60832688e-02f, 1.58719218e-02f, 1.56585249e-02f, - 1.54431523e-02f, 1.52257720e-02f, 1.50065178e-02f, 1.47852970e-02f, 1.45621674e-02f, 1.43372901e-02f, - 1.41105059e-02f, 1.38819590e-02f, 1.36516889e-02f, 1.34196283e-02f, 1.31859369e-02f, 1.29505582e-02f, - 1.27135563e-02f, 1.24749505e-02f, 1.22348100e-02f, 1.19930753e-02f, 1.17499083e-02f, 1.15052410e-02f, - 1.12591536e-02f, 1.10116665e-02f, 1.07628043e-02f, 1.05126320e-02f, 1.02611414e-02f, 1.00084032e-02f, - 9.75444164e-03f, 9.49929242e-03f, 9.24295359e-03f, 8.98550013e-03f, 8.72698180e-03f, 8.46736284e-03f, - 8.20677902e-03f, 7.94516492e-03f, 7.68261718e-03f, 7.41916791e-03f, 7.15481570e-03f, 6.88966045e-03f, - 6.62367393e-03f, 6.35692660e-03f, 6.08942491e-03f, 5.82126284e-03f, 5.55241337e-03f, 5.28296467e-03f, - 5.01283287e-03f, 4.74224210e-03f, 4.47111531e-03f, 4.19948821e-03f, 3.92740714e-03f, 3.65496810e-03f, - 3.38211695e-03f, 3.10898667e-03f, 2.83553274e-03f, 2.56177223e-03f, 2.28779866e-03f, 2.01367096e-03f, - 1.73937030e-03f, 1.46497992e-03f, 1.19049101e-03f, 9.15956887e-04f, 6.41449769e-04f, 3.66935004e-04f, - 9.25038422e-05f, -1.81800090e-04f, -4.55994013e-04f, -7.29977326e-04f, -1.00376812e-03f, -1.27729467e-03f, - -1.55055396e-03f, -1.82344378e-03f, -2.09602247e-03f, -2.36818896e-03f, -2.63987930e-03f, -2.91117931e-03f, - -3.18190061e-03f, -3.45211557e-03f, -3.72173958e-03f, -3.99075039e-03f, -4.25911319e-03f, -4.52682991e-03f, - -4.79375627e-03f, -5.05999054e-03f, -5.32537569e-03f, -5.58999026e-03f, -5.85372053e-03f, -6.11654243e-03f, - -6.37844761e-03f, -6.63939347e-03f, -6.89928643e-03f, -7.15822481e-03f, -7.41604971e-03f, -7.67280175e-03f, - -7.92838573e-03f, -8.18281011e-03f, -8.43601779e-03f, -8.68802170e-03f, -8.93874544e-03f, -9.18818453e-03f, - -9.43620552e-03f, -9.68296908e-03f, -9.92823314e-03f, -1.01721288e-02f, -1.04145516e-02f, -1.06554768e-02f, - -1.08948654e-02f, -1.11326784e-02f, -1.13689269e-02f, -1.16035516e-02f, -1.18365235e-02f, -1.20678128e-02f, - -1.22973607e-02f, -1.25251791e-02f, -1.27513019e-02f, -1.29755341e-02f, -1.31979673e-02f, -1.34185188e-02f, - -1.36372031e-02f, -1.38539302e-02f, -1.40687941e-02f, -1.42816360e-02f, -1.44924703e-02f, -1.47012787e-02f, - -1.49080511e-02f, -1.51127496e-02f, -1.53152937e-02f, -1.55157491e-02f, -1.57139906e-02f, -1.59101370e-02f, - -1.61039666e-02f, -1.62956493e-02f, -1.64850252e-02f, -1.66721416e-02f, -1.68569535e-02f, -1.70393578e-02f, - -1.72194752e-02f, -1.73972242e-02f, -1.75725358e-02f, -1.77454697e-02f, -1.79158806e-02f, -1.80838799e-02f, - -1.82493690e-02f, -1.84123844e-02f, -1.85728064e-02f, -1.87307267e-02f, -1.88860540e-02f, -1.90387930e-02f, - -1.91889246e-02f, -1.93364292e-02f, -1.94812926e-02f, -1.96234999e-02f, -1.97630192e-02f, -1.98997475e-02f, - -2.00338659e-02f, -2.01652344e-02f, -2.02938397e-02f, -2.04196601e-02f, -2.05426988e-02f, -2.06629410e-02f, - -2.07803610e-02f, -2.08949937e-02f, -2.10067897e-02f, -2.11156718e-02f, -2.12217092e-02f, -2.13248520e-02f, - -2.14251346e-02f, -2.15225040e-02f, -2.16169634e-02f, -2.17084333e-02f, -2.17970044e-02f, -2.18826558e-02f, - -2.19652892e-02f, -2.20449830e-02f, -2.21216571e-02f, -2.21954130e-02f, -2.22661039e-02f, -2.23338438e-02f, - -2.23985154e-02f, -2.24602084e-02f, -2.25188498e-02f, -2.25744567e-02f, -2.26270237e-02f, -2.26765493e-02f, - -2.27230271e-02f, -2.27664615e-02f, -2.28068065e-02f, -2.28440682e-02f, -2.28783023e-02f, -2.29094464e-02f, - -2.29375621e-02f, -2.29625268e-02f, -2.29844161e-02f, -2.30033090e-02f, -2.30189988e-02f, -2.30317198e-02f, - -2.30412596e-02f, -2.30477758e-02f, -2.30511923e-02f, -2.30515237e-02f, -2.30487843e-02f, -2.30429633e-02f, - -2.30340704e-02f, -2.30220917e-02f, -2.30070735e-02f, -2.29889275e-02f, -2.29677611e-02f, -2.29434853e-02f, - -2.29161956e-02f, -2.28858712e-02f, -2.28524663e-02f, -2.28160266e-02f, -2.27765619e-02f, -2.27340964e-02f, - -2.26885705e-02f, -2.26400391e-02f, -2.25885091e-02f, -2.25339926e-02f, -2.24764699e-02f, -2.24159924e-02f, - -2.23525171e-02f, -2.22860881e-02f, -2.22167252e-02f, -2.21443896e-02f, -2.20691823e-02f, -2.19909993e-02f, - -2.19099652e-02f, -2.18259718e-02f, -2.17391543e-02f, -2.16494369e-02f, -2.15569222e-02f, -2.14614710e-02f, - -2.13633045e-02f, -2.12622412e-02f, -2.11584129e-02f, -2.10517488e-02f, -2.09424050e-02f, -2.08302424e-02f, - -2.07153916e-02f, -2.05977999e-02f, -2.04774817e-02f, -2.03545108e-02f, -2.02288989e-02f, -2.01005848e-02f, - -1.99696741e-02f, -1.98361112e-02f, -1.96999858e-02f, -1.95612921e-02f, -1.94200277e-02f, -1.92762575e-02f, - -1.91299244e-02f, -1.89811178e-02f, -1.88298661e-02f, -1.86761567e-02f, -1.85199959e-02f, -1.83614373e-02f, - -1.82004913e-02f, -1.80371897e-02f, -1.78715631e-02f, -1.77035741e-02f, -1.75333083e-02f, -1.73608236e-02f, - -1.71860113e-02f, -1.70090514e-02f, -1.68298356e-02f, -1.66484938e-02f, -1.64650172e-02f, -1.62793299e-02f, - -1.60916799e-02f, -1.59018581e-02f, -1.57100312e-02f, -1.55161724e-02f, -1.53203836e-02f, -1.51225311e-02f, - -1.49227936e-02f, -1.47211824e-02f, -1.45176235e-02f, -1.43122829e-02f, -1.41050924e-02f, -1.38960801e-02f, - -1.36853375e-02f, -1.34728412e-02f, -1.32586302e-02f, -1.30427771e-02f, -1.28251987e-02f, -1.26060510e-02f, - -1.23853544e-02f, -1.21630554e-02f, -1.19392029e-02f, -1.17138888e-02f, -1.14870917e-02f, -1.12588830e-02f, - -1.10292578e-02f, -1.07982123e-02f, -1.05658765e-02f, -1.03321871e-02f, -1.00972975e-02f, -9.86111504e-03f, - -9.62367375e-03f, -9.38512088e-03f, -9.14538946e-03f, -8.90453522e-03f, -8.66259501e-03f, -8.41960173e-03f, - -8.17558538e-03f, -7.93064726e-03f, -7.68466214e-03f, -7.43779768e-03f, -7.19001454e-03f, -6.94143163e-03f, - -6.69203651e-03f, -6.44183524e-03f, -6.19085178e-03f, -5.93916382e-03f, -5.68684286e-03f, -5.43377624e-03f, - -5.18017831e-03f, -4.92597929e-03f, -4.67121507e-03f, -4.41599687e-03f, -4.16019659e-03f, -3.90400845e-03f, - -3.64743067e-03f, -3.39045044e-03f, -3.13313294e-03f, -2.87552024e-03f, -2.61763290e-03f, -2.35948322e-03f, - -2.10116414e-03f, -1.84269060e-03f, -1.58401393e-03f, -1.32532484e-03f, -1.06650120e-03f, -8.07733597e-04f, - -5.48870319e-04f, -2.90129890e-04f, -3.13957801e-05f, 2.27173500e-04f, 4.85627842e-04f, 7.43915731e-04f, - 1.00194173e-03f, 1.25975462e-03f, 1.51728819e-03f, 1.77449689e-03f, 2.03136020e-03f, 2.28781403e-03f, - 2.54388018e-03f, 2.79948980e-03f, 3.05459100e-03f, 3.30922741e-03f, 3.56321427e-03f, 3.81673600e-03f, - 4.06952921e-03f, 4.32168998e-03f, 4.57318695e-03f, 4.82397131e-03f, 5.07398204e-03f, 5.32315674e-03f, - 5.57160127e-03f, 5.81913414e-03f, 6.06580150e-03f, 6.31157482e-03f, 6.55632330e-03f, 6.80012803e-03f, - 7.04288921e-03f, 7.28464373e-03f, 7.52532206e-03f, 7.76487750e-03f, 8.00324296e-03f, 8.24051661e-03f, - 8.47648183e-03f, 8.71125718e-03f, 8.94481645e-03f, 9.17700045e-03f, 9.40790927e-03f, 9.63744794e-03f, - 9.86557995e-03f, 1.00922765e-02f, 1.03175272e-02f, 1.05413338e-02f, 1.07636422e-02f, 1.09843730e-02f, - 1.12035270e-02f, 1.14211323e-02f, 1.16370840e-02f, 1.18514144e-02f, 1.20640126e-02f, 1.22749388e-02f, - 1.24841288e-02f, 1.26915328e-02f, 1.28972000e-02f, 1.31010218e-02f, 1.33029945e-02f, 1.35031182e-02f, - 1.37013295e-02f, 1.38976319e-02f, 1.40919668e-02f, 1.42843526e-02f, 1.44747583e-02f, 1.46631082e-02f, - 1.48494721e-02f, 1.50336798e-02f, 1.52159082e-02f, 1.53958847e-02f, 1.55738303e-02f, 1.57495880e-02f, - 1.59231347e-02f, 1.60945159e-02f, 1.62636615e-02f, 1.64305091e-02f, 1.65951548e-02f, 1.67574552e-02f, - 1.69174709e-02f, 1.70751283e-02f, 1.72304667e-02f, 1.73834029e-02f, 1.75339794e-02f, 1.76821243e-02f, - 1.78278554e-02f, 1.79710761e-02f, 1.81119206e-02f, 1.82501977e-02f, 1.83860295e-02f, 1.85193135e-02f, - 1.86500881e-02f, 1.87782862e-02f, 1.89039615e-02f, 1.90269809e-02f, 1.91474337e-02f, 1.92653029e-02f, - 1.93805030e-02f, 1.94930908e-02f, 1.96029918e-02f, 1.97102353e-02f, 1.98147739e-02f, 1.99166603e-02f, - 2.00158261e-02f, 2.01122676e-02f, 2.02059422e-02f, 2.02969343e-02f, 2.03851346e-02f, 2.04705705e-02f, - 2.05532383e-02f, 2.06331126e-02f, 2.07101942e-02f, 2.07844552e-02f, 2.08559417e-02f, 2.09246040e-02f, - 2.09903978e-02f, 2.10534191e-02f, 2.11134897e-02f, 2.11708071e-02f, 2.12252488e-02f, 2.12768113e-02f, - 2.13255119e-02f, 2.13713381e-02f, 2.14143016e-02f, 2.14543673e-02f, 2.14915399e-02f, 2.15257864e-02f, - 2.15571884e-02f, 2.15857151e-02f, 2.16112856e-02f, 2.16339803e-02f, 2.16538018e-02f, 2.16706406e-02f, - 2.16846505e-02f, 2.16957167e-02f, 2.17038950e-02f, 2.17091480e-02f, 2.17114958e-02f, 2.17109402e-02f, - 2.17075142e-02f, 2.17011148e-02f, 2.16918677e-02f, 2.16797239e-02f, 2.16646786e-02f, 2.16467322e-02f, - 2.16259292e-02f, 2.16022076e-02f, 2.15756336e-02f, 2.15461517e-02f, 2.15138144e-02f, 2.14786524e-02f, - 2.14405680e-02f, 2.13996681e-02f, 2.13559111e-02f, 2.13093764e-02f, 2.12599316e-02f, 2.12077050e-02f, - 2.11526617e-02f, 2.10948046e-02f, 2.10341587e-02f, 2.09707225e-02f, 2.09045056e-02f, 2.08355301e-02f, - 2.07638056e-02f, 2.06893319e-02f, 2.06121042e-02f, 2.05321638e-02f, 2.04494874e-02f, 2.03641994e-02f, - 2.02761552e-02f, 2.01854451e-02f, 2.00920465e-02f, 1.99960454e-02f, 1.98974570e-02f, 1.97961892e-02f, - 1.96922964e-02f, 1.95858199e-02f, 1.94768503e-02f, 1.93652445e-02f, 1.92511379e-02f, 1.91344428e-02f, - 1.90153144e-02f, 1.88937016e-02f, 1.87695780e-02f, 1.86430022e-02f, 1.85139882e-02f, 1.83825823e-02f, - 1.82486974e-02f, 1.81125527e-02f, 1.79739168e-02f, 1.78330666e-02f, 1.76898239e-02f, 1.75442531e-02f, - 1.73964450e-02f, 1.72463150e-02f, 1.70940431e-02f, 1.69394865e-02f, 1.67827893e-02f, 1.66238295e-02f, - 1.64627799e-02f, 1.62995654e-02f, 1.61342872e-02f, 1.59668732e-02f, 1.57974224e-02f, 1.56259453e-02f, - 1.54524353e-02f, 1.52769578e-02f, 1.50994804e-02f, 1.49201045e-02f, 1.47387825e-02f, 1.45555602e-02f, - 1.43705005e-02f, 1.41836218e-02f, 1.39948800e-02f, 1.38043385e-02f, 1.36120982e-02f, 1.34180895e-02f, - 1.32223633e-02f, 1.30249568e-02f, 1.28258903e-02f, 1.26252397e-02f, 1.24229477e-02f, 1.22191068e-02f, - 1.20137056e-02f, 1.18068120e-02f, 1.15983987e-02f, 1.13885617e-02f, 1.11772763e-02f, 1.09645740e-02f, - 1.07505143e-02f, 1.05350946e-02f, 1.03184350e-02f, 1.01004177e-02f, 9.88114935e-03f, 9.66067525e-03f, - 9.43899084e-03f, 9.21622011e-03f, 8.99222105e-03f, 8.76716858e-03f, 8.54098468e-03f, 8.31383776e-03f, - 8.08562931e-03f, 7.85650920e-03f, 7.62632890e-03f, 7.39533239e-03f, 7.16335697e-03f, 6.93058228e-03f, - 6.69703894e-03f, 6.46259974e-03f, 6.22745525e-03f, 5.99158122e-03f, 5.75499586e-03f, 5.51776320e-03f, - 5.27991079e-03f, 5.04145429e-03f, 4.80237096e-03f, 4.56277701e-03f, 4.32272582e-03f, 4.08216441e-03f, - 3.84119133e-03f, 3.59977700e-03f, 3.35803976e-03f, 3.11592887e-03f, 2.87349184e-03f, 2.63080306e-03f, - 2.38791037e-03f, 2.14473726e-03f, 1.90138902e-03f, 1.65793102e-03f, 1.41433114e-03f, 1.17070432e-03f, - 9.26978245e-04f, 6.83255005e-04f, 4.39540516e-04f, 1.95897146e-04f, -4.76774072e-05f, -2.91130413e-04f, - -5.34465370e-04f, -7.77552249e-04f, -1.02049271e-03f, -1.26314678e-03f, -1.50557143e-03f, -1.74762800e-03f, - -1.98935483e-03f, -2.23074443e-03f, -2.47169320e-03f, -2.71221290e-03f, -2.95225345e-03f, -3.19180211e-03f, - -3.43083292e-03f, -3.66924624e-03f, -3.90709595e-03f, -4.14430851e-03f, -4.38089733e-03f, -4.61676637e-03f, - -4.85185506e-03f, -5.08624493e-03f, -5.31986670e-03f, -5.55263560e-03f, -5.78460222e-03f, -6.01561162e-03f, - -6.24578780e-03f, -6.47497974e-03f, -6.70322325e-03f, -6.93046201e-03f, -7.15667683e-03f, -7.38184143e-03f, - -7.60587203e-03f, -7.82881236e-03f, -8.05063439e-03f, -8.27127185e-03f, -8.49064227e-03f, -8.70879758e-03f, - -8.92572003e-03f, -9.14135138e-03f, -9.35570459e-03f, -9.56862590e-03f, -9.78019828e-03f, -9.99036426e-03f, - -1.01991026e-02f, -1.04063964e-02f, -1.06121776e-02f, -1.08164753e-02f, -1.10192203e-02f, -1.12203930e-02f, - -1.14199795e-02f, -1.16179548e-02f, -1.18142580e-02f, -1.20089228e-02f, -1.22019014e-02f, -1.23931236e-02f, - -1.25826253e-02f, -1.27703548e-02f, -1.29562895e-02f, -1.31404276e-02f, -1.33226827e-02f, -1.35030963e-02f, - -1.36815946e-02f, -1.38582058e-02f, -1.40328979e-02f, -1.42056426e-02f, -1.43763415e-02f, -1.45450859e-02f, - -1.47118351e-02f, -1.48764824e-02f, -1.50391186e-02f, -1.51995935e-02f, -1.53580302e-02f, -1.55143194e-02f, - -1.56684973e-02f, -1.58204417e-02f, -1.59702324e-02f, -1.61178018e-02f, -1.62631789e-02f, -1.64062986e-02f, - -1.65471706e-02f, -1.66857339e-02f, -1.68220577e-02f, -1.69560222e-02f, -1.70876337e-02f, -1.72169422e-02f, - -1.73438774e-02f, -1.74684216e-02f, -1.75906094e-02f, -1.77103393e-02f, -1.78277023e-02f, -1.79425799e-02f, - -1.80549835e-02f, -1.81649964e-02f, -1.82724466e-02f, -1.83774768e-02f, -1.84799478e-02f, -1.85799148e-02f, - -1.86773916e-02f, -1.87722498e-02f, -1.88645903e-02f, -1.89543294e-02f, -1.90415664e-02f, -1.91261588e-02f, - -1.92081653e-02f, -1.92875803e-02f, -1.93643578e-02f, -1.94385047e-02f, -1.95100431e-02f, -1.95789376e-02f, - -1.96451277e-02f, -1.97087240e-02f, -1.97696067e-02f, -1.98278289e-02f, -1.98833999e-02f, -1.99362433e-02f, - -1.99864103e-02f, -2.00338632e-02f, -2.00786634e-02f, -2.01207319e-02f, -2.01600767e-02f, -2.01966960e-02f, - -2.02306156e-02f, -2.02617635e-02f, -2.02903044e-02f, -2.03160248e-02f, -2.03390288e-02f, -2.03592565e-02f, - -2.03768270e-02f, -2.03916295e-02f, -2.04036861e-02f, -2.04130063e-02f, -2.04196068e-02f, -2.04234874e-02f, - -2.04246185e-02f, -2.04229838e-02f, -2.04186244e-02f, -2.04115543e-02f, -2.04017959e-02f, -2.03892258e-02f, - -2.03739909e-02f, -2.03560046e-02f, -2.03353183e-02f, -2.03119232e-02f, -2.02857984e-02f, -2.02570048e-02f, - -2.02254563e-02f, -2.01912963e-02f, -2.01543752e-02f, -2.01148033e-02f, -2.00725779e-02f, -2.00276504e-02f, - -1.99800712e-02f, -1.99298354e-02f, -1.98769621e-02f, -1.98214521e-02f, -1.97633507e-02f, -1.97025486e-02f, - -1.96392211e-02f, -1.95732528e-02f, -1.95046857e-02f, -1.94335200e-02f, -1.93598259e-02f, -1.92835964e-02f, - -1.92047555e-02f, -1.91234514e-02f, -1.90395479e-02f, -1.89531936e-02f, -1.88642930e-02f, -1.87729657e-02f, - -1.86790818e-02f, -1.85828304e-02f, -1.84840784e-02f, -1.83829271e-02f, -1.82793617e-02f, -1.81733955e-02f, - -1.80650213e-02f, -1.79542991e-02f, -1.78412044e-02f, -1.77257975e-02f, -1.76080273e-02f, -1.74879979e-02f, - -1.73656665e-02f, -1.72410793e-02f, -1.71142399e-02f, -1.69851277e-02f, -1.68538362e-02f, -1.67203517e-02f, - -1.65846763e-02f, -1.64468417e-02f, -1.63068871e-02f, -1.61647915e-02f, -1.60205911e-02f, -1.58743243e-02f, - -1.57260134e-02f, -1.55756591e-02f, -1.54232707e-02f, -1.52688917e-02f, -1.51125446e-02f, -1.49542232e-02f, - -1.47940189e-02f, -1.46318587e-02f, -1.44678448e-02f, -1.43019626e-02f, -1.41342687e-02f, -1.39646960e-02f, - -1.37934110e-02f, -1.36202535e-02f, -1.34454518e-02f, -1.32688616e-02f, -1.30906089e-02f, -1.29106560e-02f, - -1.27290961e-02f, -1.25458882e-02f, -1.23611292e-02f, -1.21747549e-02f, -1.19868203e-02f, -1.17973803e-02f, - -1.16064649e-02f, -1.14140947e-02f, -1.12202394e-02f, -1.10250087e-02f, -1.08284031e-02f, -1.06304049e-02f, - -1.04310654e-02f, -1.02304387e-02f, -1.00285272e-02f, -9.82538804e-03f, -9.62100387e-03f, -9.41539680e-03f, - -9.20870406e-03f, -9.00079957e-03f, -8.79181703e-03f, -8.58173974e-03f, -8.37062008e-03f, -8.15847422e-03f, - -7.94531912e-03f, -7.73122005e-03f, -7.51614402e-03f, -7.30022261e-03f, -7.08340554e-03f, -6.86569170e-03f, - -6.64717110e-03f, -6.42788308e-03f, -6.20786317e-03f, -5.98706870e-03f, -5.76558459e-03f, -5.54341520e-03f, - -5.32062868e-03f, -5.09724156e-03f, -4.87321060e-03f, -4.64866632e-03f, -4.42361163e-03f, -4.19812798e-03f, - -3.97208271e-03f, -3.74564084e-03f, -3.51881507e-03f, -3.29160989e-03f, -3.06407846e-03f, -2.83626240e-03f, - -2.60813143e-03f, -2.37976950e-03f, -2.15116576e-03f, -1.92244127e-03f, -1.69350196e-03f, -1.46447906e-03f, - -1.23536215e-03f, -1.00613472e-03f, -7.76945051e-04f, -5.47727722e-04f, -3.18566460e-04f, -8.94133078e-05f, - 1.39590635e-04f, 3.68517388e-04f, 5.97258917e-04f, 8.25791783e-04f, 1.05417696e-03f, 1.28227149e-03f, - 1.51013869e-03f, 1.73762413e-03f, 1.96481493e-03f, 2.19164113e-03f, 2.41804199e-03f, 2.64406847e-03f, - 2.86955077e-03f, 3.09465060e-03f, 3.31917977e-03f, 3.54312967e-03f, 3.76656706e-03f, 3.98933988e-03f, - 4.21151865e-03f, 4.43299633e-03f, 4.65381960e-03f, 4.87391105e-03f, 5.09325008e-03f, 5.31175215e-03f, - 5.52950355e-03f, 5.74638547e-03f, 5.96241057e-03f, 6.17750061e-03f, 6.39173523e-03f, 6.60497276e-03f, - 6.81726492e-03f, 7.02847747e-03f, 7.23868683e-03f, 7.44783919e-03f, 7.65591872e-03f, 7.86283591e-03f, - 8.06863099e-03f, 8.27322149e-03f, 8.47663671e-03f, 8.67885096e-03f, 8.87974772e-03f, 9.07937915e-03f, - 9.27772394e-03f, 9.47474396e-03f, 9.67038422e-03f, 9.86466144e-03f, 1.00574929e-02f, 1.02489103e-02f, - 1.04388666e-02f, 1.06273238e-02f, 1.08143033e-02f, 1.09997114e-02f, 1.11835710e-02f, 1.13658712e-02f, - 1.15465454e-02f, 1.17256122e-02f, 1.19030043e-02f, 1.20787219e-02f, 1.22527351e-02f, 1.24250491e-02f, - 1.25956128e-02f, 1.27643981e-02f, 1.29314160e-02f, 1.30966363e-02f, 1.32600290e-02f, 1.34214853e-02f, - 1.35811328e-02f, 1.37388828e-02f, 1.38947473e-02f, 1.40486919e-02f, 1.42006421e-02f, 1.43505849e-02f, - 1.44986041e-02f, 1.46446076e-02f, 1.47885658e-02f, 1.49304630e-02f, 1.50703103e-02f, 1.52080761e-02f, - 1.53437476e-02f, 1.54772751e-02f, 1.56087313e-02f, 1.57379639e-02f, 1.58650701e-02f, 1.59899686e-02f, - 1.61126706e-02f, 1.62332198e-02f, 1.63514790e-02f, 1.64674738e-02f, 1.65812554e-02f, 1.66927469e-02f, - 1.68019709e-02f, 1.69088631e-02f, 1.70134601e-02f, 1.71157250e-02f, 1.72156675e-02f, 1.73132391e-02f, - 1.74084251e-02f, 1.75012908e-02f, 1.75917529e-02f, 1.76797775e-02f, 1.77654367e-02f, 1.78486392e-02f, - 1.79294880e-02f, 1.80078026e-02f, 1.80837316e-02f, 1.81571738e-02f, 1.82281916e-02f, 1.82966991e-02f, - 1.83627255e-02f, 1.84262621e-02f, 1.84873344e-02f, 1.85458710e-02f, 1.86019038e-02f, 1.86554046e-02f, - 1.87063679e-02f, 1.87548776e-02f, 1.88007985e-02f, 1.88441730e-02f, 1.88850183e-02f, 1.89233529e-02f, - 1.89590709e-02f, 1.89922849e-02f, 1.90229017e-02f, 1.90510025e-02f, 1.90764803e-02f, 1.90993897e-02f, - 1.91197720e-02f, 1.91376008e-02f, 1.91528106e-02f, 1.91654870e-02f, 1.91755629e-02f, 1.91830929e-02f, - 1.91879868e-02f, 1.91904125e-02f, 1.91902096e-02f, 1.91873840e-02f, 1.91820878e-02f, 1.91741209e-02f, - 1.91636997e-02f, 1.91506441e-02f, 1.91350830e-02f, 1.91168999e-02f, 1.90962023e-02f, 1.90729437e-02f, - 1.90471818e-02f, 1.90188601e-02f, 1.89879740e-02f, 1.89545771e-02f, 1.89186356e-02f, 1.88802592e-02f, - 1.88392816e-02f, 1.87958452e-02f, 1.87498693e-02f, 1.87014424e-02f, 1.86505298e-02f, 1.85971265e-02f, - 1.85412869e-02f, 1.84829525e-02f, 1.84221958e-02f, 1.83589933e-02f, 1.82933758e-02f, 1.82253224e-02f, - 1.81548391e-02f, 1.80819697e-02f, 1.80067248e-02f, 1.79291273e-02f, 1.78490986e-02f, 1.77667470e-02f, - 1.76820877e-02f, 1.75950783e-02f, 1.75057218e-02f, 1.74140908e-02f, 1.73201837e-02f, 1.72239646e-02f, - 1.71255120e-02f, 1.70247905e-02f, 1.69218580e-02f, 1.68166979e-02f, 1.67093011e-02f, 1.65997775e-02f, - 1.64880218e-02f, 1.63741641e-02f, 1.62580938e-02f, 1.61399732e-02f, 1.60197046e-02f, 1.58974273e-02f, - 1.57729522e-02f, 1.56465034e-02f, 1.55179496e-02f, 1.53874166e-02f, 1.52549543e-02f, 1.51203758e-02f, - 1.49839775e-02f, 1.48454853e-02f, 1.47051841e-02f, 1.45629394e-02f, 1.44187906e-02f, 1.42727962e-02f, - 1.41249815e-02f, 1.39753378e-02f, 1.38238423e-02f, 1.36705929e-02f, 1.35155839e-02f, 1.33588865e-02f, - 1.32003957e-02f, 1.30402164e-02f, 1.28783897e-02f, 1.27149665e-02f, 1.25498604e-02f, 1.23831307e-02f, - 1.22148298e-02f, 1.20449908e-02f, 1.18736456e-02f, 1.17007433e-02f, 1.15263435e-02f, 1.13505090e-02f, - 1.11732360e-02f, 1.09945349e-02f, 1.08144731e-02f, 1.06330154e-02f, 1.04502297e-02f, 1.02661301e-02f, - 1.00807306e-02f, 9.89409102e-03f, 9.70619716e-03f, 9.51705410e-03f, 9.32682725e-03f, 9.13534725e-03f, - 8.94276150e-03f, 8.74905388e-03f, 8.55429764e-03f, 8.35846203e-03f, 8.16157035e-03f, 7.96373007e-03f, - 7.76488014e-03f, 7.56513277e-03f, 7.36440445e-03f, 7.16281552e-03f, 6.96035728e-03f, 6.75708742e-03f, - 6.55291246e-03f, 6.34806027e-03f, 6.14240850e-03f, 5.93602938e-03f, 5.72893935e-03f, 5.52122490e-03f, - 5.31282310e-03f, 5.10385043e-03f, 4.89421822e-03f, 4.68411474e-03f, 4.47343471e-03f, 4.26223801e-03f, - 4.05062726e-03f, 3.83853489e-03f, 3.62599944e-03f, 3.41310971e-03f, 3.19984882e-03f, 2.98629690e-03f, - 2.77240829e-03f, 2.55826282e-03f, 2.34386419e-03f, 2.12927566e-03f, 1.91450335e-03f, 1.69950054e-03f, - 1.48445361e-03f, 1.26927781e-03f, 1.05402841e-03f, 8.38774245e-04f, 6.23456393e-04f, 4.08178658e-04f, - 1.92952789e-04f, -2.22134718e-05f, -2.37264041e-04f, -4.52185674e-04f, -6.66914413e-04f, -8.81517867e-04f, - -1.09585535e-03f, -1.30995309e-03f, -1.52375841e-03f, -1.73730978e-03f, -1.95049223e-03f, -2.16335121e-03f, - -2.37576087e-03f, -2.58780028e-03f, -2.79935142e-03f, -3.01046063e-03f, -3.22108715e-03f, -3.43113347e-03f, - -3.64064505e-03f, -3.84955971e-03f, -4.05788427e-03f, -4.26554078e-03f, -4.47256913e-03f, -4.67883456e-03f, - -4.88446559e-03f, -5.08927704e-03f, -5.29333495e-03f, -5.49656758e-03f, -5.69899272e-03f, -5.90052801e-03f, - -6.10122113e-03f, -6.30098146e-03f, -6.49981242e-03f, -6.69764959e-03f, -6.89455112e-03f, -7.09039127e-03f, - -7.28517987e-03f, -7.47893681e-03f, -7.67159785e-03f, -7.86309353e-03f, -8.05354694e-03f, -8.24270912e-03f, - -8.43077907e-03f, -8.61756462e-03f, -8.80313376e-03f, -8.98742785e-03f, -9.17043205e-03f, -9.35213754e-03f, - -9.53250661e-03f, -9.71149905e-03f, -9.88910969e-03f, -1.00653077e-02f, -1.02400837e-02f, -1.04133639e-02f, - -1.05852272e-02f, -1.07555594e-02f, -1.09243841e-02f, -1.10916721e-02f, -1.12573881e-02f, -1.14214943e-02f, - -1.15840126e-02f, -1.17449199e-02f, -1.19041689e-02f, -1.20617042e-02f, -1.22175736e-02f, -1.23717653e-02f, - -1.25242181e-02f, -1.26749141e-02f, -1.28238213e-02f, -1.29709368e-02f, -1.31162840e-02f, -1.32597386e-02f, - -1.34014087e-02f, -1.35412500e-02f, -1.36791107e-02f, -1.38151794e-02f, -1.39492506e-02f, -1.40814015e-02f, - -1.42116097e-02f, -1.43398852e-02f, -1.44661575e-02f, -1.45904607e-02f, -1.47127004e-02f, -1.48329073e-02f, - -1.49511122e-02f, -1.50672074e-02f, -1.51813042e-02f, -1.52932728e-02f, -1.54031017e-02f, -1.55108563e-02f, - -1.56164813e-02f, -1.57200032e-02f, -1.58212556e-02f, -1.59204720e-02f, -1.60174064e-02f, -1.61121967e-02f, - -1.62047685e-02f, -1.62951315e-02f, -1.63832862e-02f, -1.64691718e-02f, -1.65528348e-02f, -1.66342408e-02f, - -1.67133464e-02f, -1.67902346e-02f, -1.68647690e-02f, -1.69370454e-02f, -1.70070308e-02f, -1.70746363e-02f, - -1.71400202e-02f, -1.72029838e-02f, -1.72636970e-02f, -1.73220078e-02f, -1.73780202e-02f, -1.74316067e-02f, - -1.74829047e-02f, -1.75318046e-02f, -1.75783075e-02f, -1.76224643e-02f, -1.76642330e-02f, -1.77036249e-02f, - -1.77405888e-02f, -1.77752212e-02f, -1.78074063e-02f, -1.78371547e-02f, -1.78645861e-02f, -1.78895709e-02f, - -1.79121439e-02f, -1.79323312e-02f, -1.79500317e-02f, -1.79654212e-02f, -1.79783032e-02f, -1.79888086e-02f, - -1.79969076e-02f, -1.80026109e-02f, -1.80058855e-02f, -1.80066998e-02f, -1.80051365e-02f, -1.80011367e-02f, - -1.79947856e-02f, -1.79859921e-02f, -1.79747639e-02f, -1.79611628e-02f, -1.79451575e-02f, -1.79267457e-02f, - -1.79059750e-02f, -1.78827564e-02f, -1.78571871e-02f, -1.78292758e-02f, -1.77989291e-02f, -1.77662226e-02f, - -1.77311314e-02f, -1.76937109e-02f, -1.76539558e-02f, -1.76118289e-02f, -1.75673615e-02f, -1.75205316e-02f, - -1.74714186e-02f, -1.74200102e-02f, -1.73662620e-02f, -1.73101491e-02f, -1.72518413e-02f, -1.71912092e-02f, - -1.71282869e-02f, -1.70631269e-02f, -1.69956810e-02f, -1.69260101e-02f, -1.68541496e-02f, -1.67799588e-02f, - -1.67036462e-02f, -1.66250808e-02f, -1.65443095e-02f, -1.64614188e-02f, -1.63763452e-02f, -1.62890881e-02f, - -1.61996845e-02f, -1.61082299e-02f, -1.60145520e-02f, -1.59188448e-02f, -1.58210545e-02f, -1.57211344e-02f, - -1.56192077e-02f, -1.55151794e-02f, -1.54091927e-02f, -1.53011388e-02f, -1.51910856e-02f, -1.50790707e-02f, - -1.49650937e-02f, -1.48491499e-02f, -1.47312606e-02f, -1.46114746e-02f, -1.44897858e-02f, -1.43662187e-02f, - -1.42407788e-02f, -1.41134406e-02f, -1.39843466e-02f, -1.38533997e-02f, -1.37206800e-02f, -1.35861719e-02f, - -1.34498738e-02f, -1.33118943e-02f, -1.31721468e-02f, -1.30307724e-02f, -1.28876621e-02f, -1.27428813e-02f, - -1.25964896e-02f, -1.24484917e-02f, -1.22988584e-02f, -1.21477016e-02f, -1.19949076e-02f, -1.18406384e-02f, - -1.16848139e-02f, -1.15275825e-02f, -1.13687780e-02f, -1.12086153e-02f, -1.10469667e-02f, -1.08839444e-02f, - -1.07194886e-02f, -1.05537452e-02f, -1.03866097e-02f, -1.02182136e-02f, -1.00484824e-02f, -9.87751418e-03f, - -9.70528337e-03f, -9.53183691e-03f, -9.35721941e-03f, -9.18139870e-03f, -9.00446406e-03f, -8.82637107e-03f, - -8.64720154e-03f, -8.46694234e-03f, -8.28567335e-03f, -8.10335577e-03f, -7.92002272e-03f, -7.73573286e-03f, - -7.55050495e-03f, -7.36434561e-03f, -7.17725197e-03f, -6.98932335e-03f, -6.80051318e-03f, -6.61092704e-03f, - -6.42053470e-03f, -6.22936486e-03f, -6.03744499e-03f, -5.84483253e-03f, -5.65150449e-03f, -5.45750282e-03f, - -5.26290461e-03f, -5.06760377e-03f, -4.87184126e-03f, -4.67539493e-03f, -4.47852857e-03f, -4.28108377e-03f, - -4.08314025e-03f, -3.88484233e-03f, -3.68603923e-03f, -3.48687482e-03f, -3.28729292e-03f, -3.08738615e-03f, - -2.88718483e-03f, -2.68668092e-03f, -2.48591700e-03f, -2.28488154e-03f, -2.08365838e-03f, -1.88226522e-03f, - -1.68071213e-03f, -1.47900348e-03f, -1.27722274e-03f, -1.07534039e-03f, -8.73462610e-04f, -6.71507290e-04f, - -4.69588017e-04f, -2.67674214e-04f, -6.58544167e-05f, 1.35879885e-04f, 3.37553983e-04f, 5.39017404e-04f, - 7.40333380e-04f, 9.41440990e-04f, 1.14235425e-03f, 1.34301814e-03f, 1.54342429e-03f, 1.74347047e-03f, - 1.94317399e-03f, 2.14259847e-03f, 2.34160857e-03f, 2.54021009e-03f, 2.73838913e-03f, 2.93607587e-03f, - 3.13326074e-03f, 3.32995053e-03f, 3.52616137e-03f, 3.72174557e-03f, 3.91671684e-03f, 4.11109445e-03f, - 4.30483270e-03f, 4.49789388e-03f, 4.69025918e-03f, 4.88192379e-03f, 5.07281845e-03f, 5.26296158e-03f, - 5.45228387e-03f, 5.64078647e-03f, 5.82847198e-03f, 6.01528485e-03f, 6.20115133e-03f, 6.38614938e-03f, - 6.57015779e-03f, 6.75322172e-03f, 6.93534641e-03f, 7.11637114e-03f, 7.29638156e-03f, 7.47533742e-03f, - 7.65316553e-03f, 7.82997393e-03f, 8.00552131e-03f, 8.18003157e-03f, 8.35329332e-03f, 8.52538954e-03f, - 8.69623060e-03f, 8.86582034e-03f, 9.03416893e-03f, 9.20121301e-03f, 9.36693888e-03f, 9.53129006e-03f, - 9.69435886e-03f, 9.85602175e-03f, 1.00162885e-02f, 1.01751234e-02f, 1.03325437e-02f, 1.04884208e-02f, - 1.06428971e-02f, 1.07958749e-02f, 1.09473128e-02f, 1.10971926e-02f, 1.12455322e-02f, 1.13922765e-02f, - 1.15374682e-02f, 1.16809971e-02f, 1.18229073e-02f, 1.19631499e-02f, 1.21017158e-02f, 1.22386563e-02f, - 1.23738019e-02f, 1.25073133e-02f, 1.26390231e-02f, 1.27689828e-02f, 1.28971594e-02f, 1.30235727e-02f, - 1.31481661e-02f, 1.32709644e-02f, 1.33918635e-02f, 1.35109520e-02f, 1.36281347e-02f, 1.37435146e-02f, - 1.38569288e-02f, 1.39684457e-02f, 1.40780323e-02f, 1.41857108e-02f, 1.42913696e-02f, 1.43951427e-02f, - 1.44968516e-02f, 1.45966533e-02f, 1.46943729e-02f, 1.47901091e-02f, 1.48838352e-02f, 1.49755043e-02f, - 1.50651123e-02f, 1.51526866e-02f, 1.52381412e-02f, 1.53215561e-02f, 1.54028547e-02f, 1.54820350e-02f, - 1.55591487e-02f, 1.56340900e-02f, 1.57069178e-02f, 1.57776061e-02f, 1.58461639e-02f, 1.59125258e-02f, - 1.59767620e-02f, 1.60387954e-02f, 1.60986357e-02f, 1.61563560e-02f, 1.62118084e-02f, 1.62650971e-02f, - 1.63161966e-02f, 1.63650341e-02f, 1.64117037e-02f, 1.64560928e-02f, 1.64982992e-02f, 1.65382317e-02f, - 1.65760217e-02f, 1.66114871e-02f, 1.66447600e-02f, 1.66757374e-02f, 1.67044733e-02f, 1.67309627e-02f, - 1.67552342e-02f, 1.67771424e-02f, 1.67968779e-02f, 1.68143388e-02f, 1.68295459e-02f, 1.68424706e-02f, - 1.68531471e-02f, 1.68615356e-02f, 1.68676980e-02f, 1.68715401e-02f, 1.68731786e-02f, 1.68725081e-02f, - 1.68695703e-02f, 1.68644169e-02f, 1.68569765e-02f, 1.68472855e-02f, 1.68353497e-02f, 1.68211136e-02f, - 1.68046969e-02f, 1.67860132e-02f, 1.67650867e-02f, 1.67419040e-02f, 1.67165062e-02f, 1.66888821e-02f, - 1.66590235e-02f, 1.66269423e-02f, 1.65926478e-02f, 1.65561840e-02f, 1.65174465e-02f, 1.64765694e-02f, - 1.64334832e-02f, 1.63882223e-02f, 1.63407765e-02f, 1.62911974e-02f, 1.62393854e-02f, 1.61854951e-02f, - 1.61294085e-02f, 1.60712025e-02f, 1.60109093e-02f, 1.59484464e-02f, 1.58838716e-02f, 1.58172692e-02f, - 1.57484917e-02f, 1.56776887e-02f, 1.56048121e-02f, 1.55298582e-02f, 1.54528653e-02f, 1.53738669e-02f, - 1.52928396e-02f, 1.52097349e-02f, 1.51246904e-02f, 1.50376526e-02f, 1.49486377e-02f, 1.48576741e-02f, - 1.47647311e-02f, 1.46699041e-02f, 1.45730895e-02f, 1.44744423e-02f, 1.43738085e-02f, 1.42713930e-02f, - 1.41670472e-02f, 1.40609187e-02f, 1.39528632e-02f, 1.38430811e-02f, 1.37314877e-02f, 1.36180032e-02f, - 1.35028440e-02f, 1.33859056e-02f, 1.32672319e-02f, 1.31468408e-02f, 1.30247521e-02f, 1.29009339e-02f, - 1.27755058e-02f, 1.26483721e-02f, 1.25196465e-02f, 1.23892913e-02f, 1.22573290e-02f, 1.21237940e-02f, - 1.19886877e-02f, 1.18520758e-02f, 1.17139022e-02f, 1.15742292e-02f, 1.14330544e-02f, 1.12904966e-02f, - 1.11464103e-02f, 1.10009274e-02f, 1.08540187e-02f, 1.07057995e-02f, 1.05561333e-02f, 1.04051610e-02f, - 1.02528725e-02f, 1.00992896e-02f, 9.94440149e-03f, 9.78826534e-03f, 9.63086578e-03f, 9.47230382e-03f, - 9.31251567e-03f, 9.15159509e-03f, 8.98947727e-03f, 8.82626091e-03f, 8.66189282e-03f, 8.49648358e-03f, - 8.33008494e-03f, 8.16250885e-03f, 7.99405047e-03f, 7.82451098e-03f, 7.65402126e-03f, 7.48262863e-03f, - 7.31030284e-03f, 7.13706370e-03f, 6.96291516e-03f, 6.78798302e-03f, 6.61222162e-03f, 6.43560568e-03f, - 6.25829473e-03f, 6.08018910e-03f, 5.90134801e-03f, 5.72178826e-03f, 5.54154815e-03f, 5.36068594e-03f, - 5.17918018e-03f, 4.99707907e-03f, 4.81435795e-03f, 4.63113902e-03f, 4.44734370e-03f, 4.26304702e-03f, - 4.07832026e-03f, 3.89304536e-03f, 3.70741433e-03f, 3.52135830e-03f, 3.33488117e-03f, 3.14809642e-03f, - 2.96094187e-03f, 2.77351029e-03f, 2.58579929e-03f, 2.39780642e-03f, 2.20962498e-03f, 2.02123439e-03f, - 1.83266312e-03f, 1.64387130e-03f, 1.45503590e-03f, 1.26602999e-03f, 1.07702313e-03f, 8.87898665e-04f, - 6.98798962e-04f, 5.09614068e-04f, 3.20542888e-04f, 1.31474773e-04f, -5.74544970e-05f, -2.46393285e-04f, - -4.35100403e-04f, -6.23707040e-04f, -8.12161081e-04f, -1.00036269e-03f, -1.18836019e-03f, -1.37611328e-03f, - -1.56361771e-03f, -1.75076873e-03f, -1.93762152e-03f, -2.12412469e-03f, -2.31020409e-03f, -2.49594612e-03f, - -2.68117551e-03f, -2.86604246e-03f, -3.05040720e-03f, -3.23431377e-03f, -3.41764547e-03f, -3.60038887e-03f, - -3.78262838e-03f, -3.96428242e-03f, -4.14526689e-03f, -4.32563956e-03f, -4.50531350e-03f, -4.68429440e-03f, - -4.86257427e-03f, -5.04015118e-03f, -5.21689235e-03f, -5.39292183e-03f, -5.56807189e-03f, -5.74243258e-03f, - -5.91593083e-03f, -6.08855152e-03f, -6.26025024e-03f, -6.43106157e-03f, -6.60089510e-03f, -6.76980286e-03f, - -6.93765717e-03f, -7.10451405e-03f, -7.27037730e-03f, -7.43513081e-03f, -7.59885329e-03f, -7.76145219e-03f, - -7.92293887e-03f, -8.08325023e-03f, -8.24246831e-03f, -8.40044578e-03f, -8.55726114e-03f, -8.71282375e-03f, - -8.86713447e-03f, -9.02018778e-03f, -9.17195102e-03f, -9.32240125e-03f, -9.47157526e-03f, -9.61939459e-03f, - -9.76575863e-03f, -9.91085612e-03f, -1.00545114e-02f, -1.01967506e-02f, -1.03375507e-02f, -1.04768747e-02f, - -1.06147367e-02f, -1.07511203e-02f, -1.08859999e-02f, -1.10193368e-02f, -1.11511153e-02f, -1.12813654e-02f, - -1.14100422e-02f, -1.15370846e-02f, -1.16625589e-02f, -1.17863701e-02f, -1.19085898e-02f, -1.20290719e-02f, - -1.21479827e-02f, -1.22651373e-02f, -1.23805927e-02f, -1.24943410e-02f, -1.26063691e-02f, -1.27166460e-02f, - -1.28251835e-02f, -1.29318888e-02f, -1.30368465e-02f, -1.31399900e-02f, -1.32413493e-02f, -1.33408719e-02f, - -1.34385361e-02f, -1.35343816e-02f, -1.36283053e-02f, -1.37204413e-02f, -1.38105976e-02f, -1.38989277e-02f, - -1.39853292e-02f, -1.40698138e-02f, -1.41523500e-02f, -1.42329707e-02f, -1.43116201e-02f, -1.43883559e-02f, - -1.44630764e-02f, -1.45358443e-02f, -1.46066047e-02f, -1.46754067e-02f, -1.47421607e-02f, -1.48069606e-02f, - -1.48697088e-02f, -1.49304355e-02f, -1.49891256e-02f, -1.50457772e-02f, -1.51003770e-02f, -1.51529494e-02f, - -1.52034240e-02f, -1.52518825e-02f, -1.52982407e-02f, -1.53425471e-02f, -1.53847512e-02f, -1.54248494e-02f, - -1.54628856e-02f, -1.54988679e-02f, -1.55326803e-02f, -1.55644632e-02f, -1.55940973e-02f, -1.56216181e-02f, - -1.56470648e-02f, -1.56703716e-02f, -1.56915623e-02f, -1.57106848e-02f, -1.57276466e-02f, -1.57425125e-02f, - -1.57552288e-02f, -1.57658452e-02f, -1.57743250e-02f, -1.57807599e-02f, -1.57849684e-02f, -1.57871440e-02f, - -1.57871201e-02f, -1.57850428e-02f, -1.57808378e-02f, -1.57744895e-02f, -1.57660740e-02f, -1.57555306e-02f, - -1.57428672e-02f, -1.57280562e-02f, -1.57112203e-02f, -1.56922429e-02f, -1.56711834e-02f, -1.56480433e-02f, - -1.56228009e-02f, -1.55954556e-02f, -1.55660582e-02f, -1.55345946e-02f, -1.55010470e-02f, -1.54654402e-02f, - -1.54278108e-02f, -1.53880701e-02f, -1.53462900e-02f, -1.53024998e-02f, -1.52567061e-02f, -1.52088402e-02f, - -1.51589724e-02f, -1.51070700e-02f, -1.50532236e-02f, -1.49973748e-02f, -1.49394928e-02f, -1.48796645e-02f, - -1.48178784e-02f, -1.47541603e-02f, -1.46884280e-02f, -1.46208142e-02f, -1.45512113e-02f, -1.44797616e-02f, - -1.44063716e-02f, -1.43310880e-02f, -1.42538763e-02f, -1.41748858e-02f, -1.40940165e-02f, -1.40111790e-02f, - -1.39266521e-02f, -1.38401799e-02f, -1.37520145e-02f, -1.36619185e-02f, -1.35701501e-02f, -1.34765243e-02f, - -1.33811825e-02f, -1.32840326e-02f, -1.31852409e-02f, -1.30846703e-02f, -1.29824272e-02f, -1.28784688e-02f, - -1.27728257e-02f, -1.26655453e-02f, -1.25566049e-02f, -1.24460624e-02f, -1.23338526e-02f, -1.22200743e-02f, - -1.21047307e-02f, -1.19877855e-02f, -1.18693271e-02f, -1.17493120e-02f, -1.16277624e-02f, -1.15047551e-02f, - -1.13802718e-02f, -1.12542667e-02f, -1.11268629e-02f, -1.09980094e-02f, -1.08677511e-02f, -1.07361133e-02f, - -1.06030629e-02f, -1.04686902e-02f, -1.03329507e-02f, -1.01959211e-02f, -1.00575732e-02f, -9.91796076e-03f, - -9.77710766e-03f, -9.63494089e-03f, -9.49164195e-03f, -9.34708196e-03f, -9.20137594e-03f, -9.05444353e-03f, - -8.90643337e-03f, -8.75727653e-03f, -8.60704833e-03f, -8.45569074e-03f, -8.30329640e-03f, -8.14988801e-03f, - -7.99543957e-03f, -7.84000859e-03f, -7.68355803e-03f, -7.52624994e-03f, -7.36791052e-03f, -7.20872586e-03f, - -7.04860579e-03f, -6.88766325e-03f, -6.72584105e-03f, -6.56324501e-03f, -6.39979668e-03f, -6.23561236e-03f, - -6.07062369e-03f, -5.90495408e-03f, -5.73855085e-03f, -5.57147966e-03f, -5.40375891e-03f, -5.23534253e-03f, - -5.06632087e-03f, -4.89673075e-03f, -4.72652484e-03f, -4.55585487e-03f, -4.38456408e-03f, -4.21279507e-03f, - -4.04063133e-03f, -3.86787386e-03f, -3.69477185e-03f, -3.52122365e-03f, -3.34736555e-03f, -3.17304722e-03f, - -2.99847761e-03f, -2.82348812e-03f, -2.64828543e-03f, -2.47280190e-03f, -2.29706954e-03f, -2.12109215e-03f, - -1.94494905e-03f, -1.76863668e-03f, -1.59215910e-03f, -1.41555486e-03f, -1.23883596e-03f, -1.06206436e-03f, - -8.85277990e-04f, -7.08384047e-04f, -5.31536972e-04f, -3.54659316e-04f, -1.77858736e-04f, -1.11672183e-06f, - 1.75569894e-04f, 3.52075313e-04f, 5.28499324e-04f, 7.04762071e-04f, 8.80848125e-04f, 1.05669067e-03f, - 1.23231463e-03f, 1.40769835e-03f, 1.58277222e-03f, 1.75757965e-03f, 1.93209060e-03f, 2.10619520e-03f, - 2.27997552e-03f, 2.45337119e-03f, 2.62629511e-03f, 2.79878392e-03f, 2.97084912e-03f, 3.14242705e-03f, - 3.31349833e-03f, 3.48398500e-03f, 3.65402586e-03f, 3.82336865e-03f, 3.99220467e-03f, 4.16039558e-03f, - 4.32788712e-03f, 4.49480427e-03f, 4.66097408e-03f, 4.82645354e-03f, 4.99122029e-03f, 5.15522203e-03f, - 5.31842376e-03f, 5.48087760e-03f, 5.64246625e-03f, 5.80324109e-03f, 5.96315984e-03f, 6.12219875e-03f, - 6.28034021e-03f, 6.43752537e-03f, 6.59380771e-03f, 6.74912491e-03f, 6.90344516e-03f, 7.05673383e-03f, - 7.20906424e-03f, 7.36026913e-03f, 7.51047049e-03f, 7.65959666e-03f, 7.80760434e-03f, 7.95447917e-03f, - 8.10020011e-03f, 8.24475205e-03f, 8.38816815e-03f, 8.53042498e-03f, 8.67136326e-03f, 8.81110835e-03f, - 8.94963363e-03f, 9.08685889e-03f, 9.22276938e-03f, 9.35744565e-03f, 9.49073908e-03f, 9.62272827e-03f, - 9.75334596e-03f, 9.88254607e-03f, 1.00104322e-02f, 1.01368621e-02f, 1.02618585e-02f, 1.03854390e-02f, - 1.05075832e-02f, 1.06282569e-02f, 1.07473700e-02f, 1.08650550e-02f, 1.09812049e-02f, 1.10958238e-02f, - 1.12089185e-02f, 1.13203917e-02f, 1.14303453e-02f, 1.15386380e-02f, 1.16454117e-02f, 1.17505693e-02f, - 1.18540226e-02f, 1.19558682e-02f, 1.20560952e-02f, 1.21545980e-02f, 1.22514744e-02f, 1.23466147e-02f, - 1.24400490e-02f, 1.25318293e-02f, 1.26218424e-02f, 1.27100546e-02f, 1.27966040e-02f, 1.28813373e-02f, - 1.29643605e-02f, 1.30455646e-02f, 1.31249513e-02f, 1.32026284e-02f, 1.32783979e-02f, 1.33523858e-02f, - 1.34245114e-02f, 1.34948268e-02f, 1.35633176e-02f, 1.36299247e-02f, 1.36946977e-02f, 1.37575687e-02f, - 1.38185977e-02f, 1.38777147e-02f, 1.39349342e-02f, 1.39902707e-02f, 1.40437021e-02f, 1.40952179e-02f, - 1.41448029e-02f, 1.41924906e-02f, 1.42382296e-02f, 1.42820604e-02f, 1.43239177e-02f, 1.43638626e-02f, - 1.44018284e-02f, 1.44378801e-02f, 1.44719443e-02f, 1.45040878e-02f, 1.45342419e-02f, 1.45624217e-02f, - 1.45886568e-02f, 1.46129181e-02f, 1.46352158e-02f, 1.46554703e-02f, 1.46738105e-02f, 1.46901337e-02f, - 1.47045657e-02f, 1.47169431e-02f, 1.47273323e-02f, 1.47357526e-02f, 1.47422213e-02f, 1.47466832e-02f, - 1.47491793e-02f, 1.47496821e-02f, 1.47482088e-02f, 1.47447656e-02f, 1.47392937e-02f, 1.47318958e-02f, - 1.47225481e-02f, 1.47112104e-02f, 1.46979018e-02f, 1.46825896e-02f, 1.46653659e-02f, 1.46461335e-02f, - 1.46250040e-02f, 1.46018812e-02f, 1.45768503e-02f, 1.45498277e-02f, 1.45208887e-02f, 1.44900386e-02f, - 1.44572098e-02f, 1.44225177e-02f, 1.43858457e-02f, 1.43473030e-02f, 1.43068739e-02f, 1.42644631e-02f, - 1.42202434e-02f, 1.41741098e-02f, 1.41261229e-02f, 1.40761944e-02f, 1.40244747e-02f, 1.39708659e-02f, - 1.39154012e-02f, 1.38581230e-02f, 1.37989863e-02f, 1.37380715e-02f, 1.36752724e-02f, 1.36107837e-02f, - 1.35443784e-02f, 1.34762683e-02f, 1.34063710e-02f, 1.33346639e-02f, 1.32612776e-02f, 1.31860576e-02f, - 1.31091998e-02f, 1.30305924e-02f, 1.29502415e-02f, 1.28682544e-02f, 1.27844955e-02f, 1.26991470e-02f, - 1.26120961e-02f, 1.25234499e-02f, 1.24330807e-02f, 1.23411197e-02f, 1.22475702e-02f, 1.21524371e-02f, - 1.20557212e-02f, 1.19573923e-02f, 1.18575544e-02f, 1.17561418e-02f, 1.16532258e-02f, 1.15488088e-02f, - 1.14428606e-02f, 1.13354638e-02f, 1.12265336e-02f, 1.11162504e-02f, 1.10044720e-02f, 1.08912801e-02f, - 1.07767136e-02f, 1.06607148e-02f, 1.05433979e-02f, 1.04246778e-02f, 1.03046356e-02f, 1.01832721e-02f, - 1.00606079e-02f, 9.93667158e-03f, 9.81145575e-03f, 9.68494766e-03f, 9.55725029e-03f, 9.42830443e-03f, - 9.29819503e-03f, 9.16685879e-03f, 9.03441327e-03f, 8.90078527e-03f, 8.76606738e-03f, 8.63016143e-03f, - 8.49322674e-03f, 8.35524238e-03f, 8.21619368e-03f, 8.07609927e-03f, 7.93497302e-03f, 7.79290142e-03f, - 7.64980400e-03f, 7.50578617e-03f, 7.36084061e-03f, 7.21496845e-03f, 7.06821031e-03f, 6.92054749e-03f, - 6.77207557e-03f, 6.62273570e-03f, 6.47257716e-03f, 6.32172634e-03f, 6.16993225e-03f, 6.01754089e-03f, - 5.86434319e-03f, 5.71048472e-03f, 5.55587972e-03f, 5.40065265e-03f, 5.24473109e-03f, 5.08825462e-03f, - 4.93111132e-03f, 4.77344291e-03f, 4.61516747e-03f, 4.45637903e-03f, 4.29703763e-03f, 4.13727951e-03f, - 3.97696239e-03f, 3.81622990e-03f, 3.65512742e-03f, 3.49351109e-03f, 3.33156848e-03f, 3.16922881e-03f, - 3.00656086e-03f, 2.84360909e-03f, 2.68032897e-03f, 2.51674010e-03f, 2.35295988e-03f, 2.18890383e-03f, - 2.02463591e-03f, 1.86020603e-03f, 1.69562789e-03f, 1.53087797e-03f, 1.36600118e-03f, 1.20099110e-03f, - 1.03594763e-03f, 8.70897112e-04f, 7.05767487e-04f, 5.40606131e-04f, 3.75458608e-04f, 2.10342770e-04f, - 4.53780142e-05f, -1.19613413e-04f, -2.84485037e-04f, -4.49215683e-04f, -6.13807578e-04f, -7.78218534e-04f, - -9.42480647e-04f, -1.10649100e-03f, -1.27025194e-03f, -1.43383334e-03f, -1.59710965e-03f, -1.76008260e-03f, - -1.92270576e-03f, -2.08499307e-03f, -2.24690915e-03f, -2.40850031e-03f, -2.56967334e-03f, -2.73033311e-03f, - -2.89064040e-03f, -3.05043570e-03f, -3.20976968e-03f, -3.36854797e-03f, -3.52681285e-03f, -3.68450382e-03f, - -3.84168352e-03f, -3.99816616e-03f, -4.15411442e-03f, -4.30940839e-03f, -4.46404544e-03f, -4.61796657e-03f, - -4.77124968e-03f, -4.92372607e-03f, -5.07552842e-03f, -5.22657778e-03f, -5.37682957e-03f, -5.52623133e-03f, - -5.67494604e-03f, -5.82269758e-03f, -5.96962779e-03f, -6.11569607e-03f, -6.26090266e-03f, -6.40511410e-03f, - -6.54843987e-03f, -6.69078734e-03f, -6.83216593e-03f, -6.97262969e-03f, -7.11199625e-03f, -7.25038986e-03f, - -7.38767558e-03f, -7.52398180e-03f, -7.65912910e-03f, -7.79323563e-03f, -7.92616724e-03f, -8.05804795e-03f, - -8.18869777e-03f, -8.31825794e-03f, -8.44656082e-03f, -8.57374321e-03f, -8.69965344e-03f, -8.82435773e-03f, - -8.94778225e-03f, -9.06997373e-03f, -9.19085276e-03f, -9.31046652e-03f, -9.42873622e-03f, -9.54572799e-03f, - -9.66135365e-03f, -9.77561210e-03f, -9.88850045e-03f, -1.00000165e-02f, -1.01101353e-02f, -1.02188313e-02f, - -1.03260890e-02f, -1.04319103e-02f, -1.05363031e-02f, -1.06392234e-02f, -1.07406494e-02f, -1.08405832e-02f, - -1.09389703e-02f, -1.10359000e-02f, -1.11312664e-02f, -1.12251327e-02f, -1.13173621e-02f, -1.14080894e-02f, - -1.14972283e-02f, -1.15847572e-02f, -1.16707289e-02f, -1.17550359e-02f, -1.18377748e-02f, -1.19187995e-02f, - -1.19983243e-02f, -1.20760482e-02f, -1.21521915e-02f, -1.22266125e-02f, -1.22994442e-02f, -1.23705058e-02f, - -1.24399055e-02f, -1.25075756e-02f, -1.25735685e-02f, -1.26377889e-02f, -1.27003566e-02f, -1.27611087e-02f, - -1.28201493e-02f, -1.28774449e-02f, -1.29329766e-02f, -1.29867349e-02f, -1.30387444e-02f, -1.30889378e-02f, - -1.31374149e-02f, -1.31840372e-02f, -1.32288962e-02f, -1.32719380e-02f, -1.33132017e-02f, -1.33526471e-02f, - -1.33902937e-02f, -1.34260694e-02f, -1.34600911e-02f, -1.34922666e-02f, -1.35225771e-02f, -1.35511340e-02f, - -1.35777731e-02f, -1.36026223e-02f, -1.36256307e-02f, -1.36467737e-02f, -1.36661148e-02f, -1.36836160e-02f, - -1.36992240e-02f, -1.37130290e-02f, -1.37249100e-02f, -1.37350403e-02f, -1.37432674e-02f, -1.37496604e-02f, - -1.37541858e-02f, -1.37569057e-02f, -1.37577154e-02f, -1.37567512e-02f, -1.37538841e-02f, -1.37491683e-02f, - -1.37426767e-02f, -1.37343014e-02f, -1.37240574e-02f, -1.37120034e-02f, -1.36981168e-02f, -1.36824235e-02f, - -1.36648601e-02f, -1.36455019e-02f, -1.36243167e-02f, -1.36013049e-02f, -1.35764525e-02f, -1.35498550e-02f, - -1.35214075e-02f, -1.34911516e-02f, -1.34591350e-02f, -1.34252964e-02f, -1.33896860e-02f, -1.33523054e-02f, - -1.33131554e-02f, -1.32722179e-02f, -1.32295697e-02f, -1.31850952e-02f, -1.31389319e-02f, -1.30909888e-02f, - -1.30413597e-02f, -1.29899505e-02f, -1.29368493e-02f, -1.28820660e-02f, -1.28255468e-02f, -1.27673694e-02f, - -1.27074461e-02f, -1.26458889e-02f, -1.25826731e-02f, -1.25177934e-02f, -1.24513163e-02f, -1.23830960e-02f, - -1.23133536e-02f, -1.22418942e-02f, -1.21689403e-02f, -1.20942936e-02f, -1.20181247e-02f, -1.19403361e-02f, - -1.18610314e-02f, -1.17801442e-02f, -1.16977211e-02f, -1.16138002e-02f, -1.15283331e-02f, -1.14413637e-02f, - -1.13529053e-02f, -1.12630101e-02f, -1.11715718e-02f, -1.10787703e-02f, -1.09844478e-02f, -1.08887527e-02f, - -1.07916248e-02f, -1.06931319e-02f, -1.05931958e-02f, -1.04919393e-02f, -1.03892847e-02f, -1.02853424e-02f, - -1.01800281e-02f, -1.00734316e-02f, -9.96552595e-03f, -9.85632862e-03f, -9.74588161e-03f, -9.63418636e-03f, - -9.52127303e-03f, -9.40709681e-03f, -9.29175032e-03f, -9.17518162e-03f, -9.05746525e-03f, -8.93860175e-03f, - -8.81858290e-03f, -8.69743723e-03f, -8.57524865e-03f, -8.45190136e-03f, -8.32751162e-03f, -8.20208558e-03f, - -8.07558820e-03f, -7.94808459e-03f, -7.81958565e-03f, -7.69010971e-03f, -7.55965240e-03f, -7.42828342e-03f, - -7.29594852e-03f, -7.16275575e-03f, -7.02859820e-03f, -6.89360430e-03f, -6.75774632e-03f, -6.62107472e-03f, - -6.48356302e-03f, -6.34525756e-03f, -6.20619548e-03f, -6.06636733e-03f, -5.92573354e-03f, -5.78445506e-03f, - -5.64243637e-03f, -5.49978793e-03f, -5.35638750e-03f, -5.21239331e-03f, -5.06776352e-03f, -4.92254684e-03f, - -4.77677734e-03f, -4.63035961e-03f, -4.48346891e-03f, -4.33596887e-03f, -4.18805224e-03f, -4.03963194e-03f, - -3.89070290e-03f, -3.74137610e-03f, -3.59160895e-03f, -3.44141511e-03f, -3.29087884e-03f, -3.13993375e-03f, - -2.98868069e-03f, -2.83712639e-03f, -2.68523383e-03f, -2.53307549e-03f, -2.38059802e-03f, -2.22798775e-03f, - -2.07506416e-03f, -1.92203963e-03f, -1.76872529e-03f, -1.61534854e-03f, -1.46178078e-03f, -1.30809953e-03f, - -1.15432016e-03f, -1.00048670e-03f, -8.46607510e-04f, -6.92684206e-04f, -5.38751556e-04f, -3.84838957e-04f, - -2.30881491e-04f, -7.70798914e-05f, 7.67466286e-05f, 2.30366145e-04f, 3.83981649e-04f, 5.37430997e-04f, - 6.90717866e-04f, 8.43853686e-04f, 9.96736254e-04f, 1.14947034e-03f, 1.30195890e-03f, 1.45417363e-03f, - 1.60612272e-03f, 1.75778137e-03f, 1.90910045e-03f, 2.06012433e-03f, 2.21073898e-03f, 2.36102816e-03f, - 2.51088468e-03f, 2.66033866e-03f, 2.80937054e-03f, 2.95793873e-03f, 3.10603445e-03f, 3.25361804e-03f, - 3.40068135e-03f, 3.54725270e-03f, 3.69323093e-03f, 3.83868504e-03f, 3.98348897e-03f, 4.12771492e-03f, - 4.27130145e-03f, 4.41425967e-03f, 4.55650020e-03f, 4.69808727e-03f, 4.83897534e-03f, 4.97913551e-03f, - 5.11855403e-03f, 5.25722372e-03f, 5.39509931e-03f, 5.53213401e-03f, 5.66841374e-03f, 5.80386852e-03f, - 5.93841989e-03f, 6.07215984e-03f, 6.20498374e-03f, 6.33687888e-03f, 6.46789007e-03f, 6.59797767e-03f, - 6.72710928e-03f, 6.85522391e-03f, 6.98237866e-03f, 7.10854894e-03f, 7.23362942e-03f, 7.35774675e-03f, - 7.48079648e-03f, 7.60276544e-03f, 7.72363753e-03f, 7.84342465e-03f, 7.96209892e-03f, 8.07960032e-03f, - 8.19602613e-03f, 8.31126277e-03f, 8.42531938e-03f, 8.53815287e-03f, 8.64983360e-03f, 8.76021998e-03f, - 8.86945233e-03f, 8.97739076e-03f, 9.08409946e-03f, 9.18954368e-03f, 9.29363777e-03f, 9.39645865e-03f, - 9.49794555e-03f, 9.59814253e-03f, 9.69698489e-03f, 9.79446383e-03f, 9.89057939e-03f, 9.98528597e-03f, - 1.00787029e-02f, 1.01706279e-02f, 1.02611362e-02f, 1.03502421e-02f, 1.04379100e-02f, 1.05241404e-02f, - 1.06089052e-02f, 1.06922102e-02f, 1.07740044e-02f, 1.08543511e-02f, 1.09331934e-02f, 1.10104822e-02f, - 1.10862859e-02f, 1.11605229e-02f, 1.12332888e-02f, 1.13044908e-02f, 1.13740912e-02f, 1.14421892e-02f, - 1.15086626e-02f, 1.15735620e-02f, 1.16369212e-02f, 1.16986202e-02f, 1.17587766e-02f, 1.18172680e-02f, - 1.18742087e-02f, 1.19294586e-02f, 1.19831315e-02f, 1.20350981e-02f, 1.20854453e-02f, 1.21342032e-02f, - 1.21812458e-02f, 1.22266544e-02f, 1.22703929e-02f, 1.23124497e-02f, 1.23528377e-02f, 1.23915469e-02f, - 1.24286113e-02f, 1.24639291e-02f, 1.24975523e-02f, 1.25295382e-02f, 1.25597591e-02f, 1.25883169e-02f, - 1.26151447e-02f, 1.26403080e-02f, 1.26637233e-02f, 1.26854732e-02f, 1.27054194e-02f, 1.27236956e-02f, - 1.27403177e-02f, 1.27551264e-02f, 1.27682669e-02f, 1.27796758e-02f, 1.27893316e-02f, 1.27973192e-02f, - 1.28035434e-02f, 1.28080835e-02f, 1.28108590e-02f, 1.28119513e-02f, 1.28112834e-02f, 1.28089502e-02f, - 1.28048164e-02f, 1.27990471e-02f, 1.27914831e-02f, 1.27823187e-02f, 1.27713563e-02f, 1.27587219e-02f, - 1.27443351e-02f, 1.27283068e-02f, 1.27105153e-02f, 1.26910837e-02f, 1.26699233e-02f, 1.26470821e-02f, - 1.26225544e-02f, 1.25963658e-02f, 1.25684420e-02f, 1.25389520e-02f, 1.25076989e-02f, 1.24748112e-02f, - 1.24402415e-02f, 1.24040611e-02f, 1.23662420e-02f, 1.23267470e-02f, 1.22856690e-02f, 1.22428675e-02f, - 1.21985584e-02f, 1.21525422e-02f, 1.21049942e-02f, 1.20557558e-02f, 1.20050172e-02f, 1.19526270e-02f, - 1.18987375e-02f, 1.18432006e-02f, 1.17861578e-02f, 1.17275091e-02f, 1.16673870e-02f, 1.16056573e-02f, - 1.15424429e-02f, 1.14777248e-02f, 1.14114460e-02f, 1.13437152e-02f, 1.12745414e-02f, 1.12037932e-02f, - 1.11316258e-02f, 1.10579870e-02f, 1.09829491e-02f, 1.09064535e-02f, 1.08284743e-02f, 1.07491630e-02f, - 1.06684047e-02f, 1.05863108e-02f, 1.05027766e-02f, 1.04179090e-02f, 1.03316862e-02f, 1.02441160e-02f, - 1.01552413e-02f, 1.00649553e-02f, 9.97350014e-03f, 9.88069825e-03f, 9.78658164e-03f, 9.69126356e-03f, - 9.59464762e-03f, 9.49684989e-03f, 9.39776643e-03f, 9.29752345e-03f, 9.19604486e-03f, 9.09343430e-03f, - 8.98959301e-03f, 8.88467115e-03f, 8.77851790e-03f, 8.67136508e-03f, 8.56298807e-03f, 8.45363189e-03f, - 8.34311169e-03f, 8.23157295e-03f, 8.11897051e-03f, 8.00532625e-03f, 7.89072788e-03f, 7.77506004e-03f, - 7.65848247e-03f, 7.54086299e-03f, 7.42232409e-03f, 7.30287423e-03f, 7.18243624e-03f, 7.06120936e-03f, - 6.93900007e-03f, 6.81603372e-03f, 6.69207348e-03f, 6.56739740e-03f, 6.44184961e-03f, 6.31553411e-03f, - 6.18843027e-03f, 6.06055434e-03f, 5.93196502e-03f, 5.80258931e-03f, 5.67256560e-03f, 5.54179464e-03f, - 5.41039307e-03f, 5.27829928e-03f, 5.14560312e-03f, 5.01224717e-03f, 4.87833152e-03f, 4.74380718e-03f, - 4.60872500e-03f, 4.47309635e-03f, 4.33697902e-03f, 4.20027882e-03f, 4.06315403e-03f, 3.92547282e-03f, - 3.78744189e-03f, 3.64890321e-03f, 3.50996502e-03f, 3.37066570e-03f, 3.23093212e-03f, 3.09091094e-03f, - 2.95050483e-03f, 2.80969688e-03f, 2.66876161e-03f, 2.52739739e-03f, 2.38586725e-03f, 2.24402751e-03f, - 2.10202642e-03f, 1.95976620e-03f, 1.81727684e-03f, 1.67471552e-03f, 1.53196285e-03f, 1.38911253e-03f, - 1.24608944e-03f, 1.10302324e-03f, 9.59864881e-04f, 8.16661195e-04f, 6.73420183e-04f, 5.30205856e-04f, - 3.86946121e-04f, 2.43743437e-04f, 1.00559568e-04f, -4.25644027e-05f, -1.85588577e-04f, -3.28510814e-04f, - -4.71303897e-04f, -6.13948158e-04f, -7.56475214e-04f, -8.98810015e-04f, -1.04091831e-03f, -1.18282749e-03f, - -1.32449228e-03f, -1.46593362e-03f, -1.60710357e-03f, -1.74794338e-03f, -1.88849929e-03f, -2.02867970e-03f, - -2.16860642e-03f, -2.30807317e-03f, -2.44719275e-03f, -2.58591168e-03f, -2.72420865e-03f, -2.86207272e-03f, - -2.99946392e-03f, -3.13637693e-03f, -3.27280227e-03f, -3.40869431e-03f, -3.54407028e-03f, -3.67891823e-03f, - -3.81316917e-03f, -3.94685760e-03f, -4.07993523e-03f, -4.21239361e-03f, -4.34419353e-03f, -4.47538388e-03f, - -4.60586249e-03f, -4.73569302e-03f, -4.86476252e-03f, -4.99318759e-03f, -5.12076582e-03f, -5.24767282e-03f, - -5.37376214e-03f, -5.49909637e-03f, -5.62359915e-03f, -5.74730923e-03f, -5.87011925e-03f, -5.99211920e-03f, - -6.11327130e-03f, -6.23349091e-03f, -6.35284924e-03f, -6.47127202e-03f, -6.58877121e-03f, -6.70527963e-03f, - -6.82088923e-03f, -6.93546587e-03f, -7.04905702e-03f, -7.16167008e-03f, -7.27322549e-03f, -7.38378317e-03f, - -7.49325743e-03f, -7.60166353e-03f, -7.70904691e-03f, -7.81529288e-03f, -7.92042914e-03f, -8.02443428e-03f, - -8.12731739e-03f, -8.22905791e-03f, -8.32966060e-03f, -8.42902904e-03f, -8.52730227e-03f, -8.62432228e-03f, - -8.72011244e-03f, -8.81470599e-03f, -8.90805736e-03f, -9.00016670e-03f, -9.09101787e-03f, -9.18060250e-03f, - -9.26892649e-03f, -9.35593051e-03f, -9.44163439e-03f, -9.52601479e-03f, -9.60904042e-03f, -9.69083032e-03f, - -9.77118634e-03f, -9.85024086e-03f, -9.92787024e-03f, -1.00041770e-02f, -1.00790807e-02f, -1.01525875e-02f, - -1.02247314e-02f, -1.02953739e-02f, -1.03646928e-02f, -1.04325030e-02f, -1.04989205e-02f, -1.05638776e-02f, - -1.06273913e-02f, -1.06894412e-02f, -1.07500102e-02f, -1.08091422e-02f, -1.08667492e-02f, -1.09228534e-02f, - -1.09775210e-02f, -1.10306168e-02f, -1.10822319e-02f, -1.11323648e-02f, -1.11809138e-02f, -1.12280103e-02f, - -1.12734527e-02f, -1.13174909e-02f, -1.13598997e-02f, -1.14008228e-02f, -1.14401133e-02f, -1.14778919e-02f, - -1.15141260e-02f, -1.15488117e-02f, -1.15818733e-02f, -1.16133652e-02f, -1.16432892e-02f, -1.16716578e-02f, - -1.16984295e-02f, -1.17235955e-02f, -1.17471943e-02f, -1.17692096e-02f, -1.17896332e-02f, -1.18084220e-02f, - -1.18256790e-02f, -1.18412550e-02f, -1.18553445e-02f, -1.18677177e-02f, -1.18786090e-02f, -1.18877878e-02f, - -1.18954274e-02f, -1.19014381e-02f, -1.19058876e-02f, -1.19087064e-02f, -1.19098861e-02f, -1.19095702e-02f, - -1.19075488e-02f, -1.19039784e-02f, -1.18988124e-02f, -1.18920479e-02f, -1.18836872e-02f, -1.18737441e-02f, - -1.18621974e-02f, -1.18490599e-02f, -1.18343668e-02f, -1.18180765e-02f, -1.18002138e-02f, -1.17807600e-02f, - -1.17597169e-02f, -1.17371579e-02f, -1.17130335e-02f, -1.16873037e-02f, -1.16600592e-02f, -1.16312268e-02f, - -1.16008679e-02f, -1.15689744e-02f, -1.15355559e-02f, -1.15005669e-02f, -1.14640918e-02f, -1.14260751e-02f, - -1.13865580e-02f, -1.13454996e-02f, -1.13029779e-02f, -1.12589423e-02f, -1.12134342e-02f, -1.11664786e-02f, - -1.11179772e-02f, -1.10680402e-02f, -1.10166257e-02f, -1.09638285e-02f, -1.09094608e-02f, -1.08538026e-02f, - -1.07966250e-02f, -1.07380625e-02f, -1.06780812e-02f, -1.06167151e-02f, -1.05539197e-02f, -1.04897586e-02f, - -1.04242305e-02f, -1.03573179e-02f, -1.02891329e-02f, -1.02195249e-02f, -1.01485368e-02f, -1.00763402e-02f, - -1.00027581e-02f, -9.92791929e-03f, -9.85170214e-03f, -9.77429966e-03f, -9.69557475e-03f, -9.61561546e-03f, - -9.53439752e-03f, -9.45195078e-03f, -9.36825535e-03f, -9.28338878e-03f, -9.19728854e-03f, -9.11000438e-03f, - -9.02157277e-03f, -8.93194802e-03f, -8.84120983e-03f, -8.74924315e-03f, -8.65625133e-03f, -8.56208689e-03f, - -8.46689400e-03f, -8.37052738e-03f, -8.27317491e-03f, -8.17468007e-03f, -8.07524253e-03f, -7.97470669e-03f, - -7.87311182e-03f, -7.77060539e-03f, -7.66703761e-03f, -7.56258752e-03f, -7.45713117e-03f, -7.35070963e-03f, - -7.24338245e-03f, -7.13510580e-03f, -7.02600059e-03f, -6.91595216e-03f, -6.80505269e-03f, -6.69330072e-03f, - -6.58072916e-03f, -6.46731013e-03f, -6.35307337e-03f, -6.23808944e-03f, -6.12230552e-03f, -6.00577117e-03f, - -5.88849230e-03f, -5.77044333e-03f, -5.65178883e-03f, -5.53235654e-03f, -5.41224250e-03f, -5.29150910e-03f, - -5.17012675e-03f, -5.04807034e-03f, -4.92545548e-03f, -4.80222499e-03f, -4.67841629e-03f, -4.55405395e-03f, - -4.42917169e-03f, -4.30370172e-03f, -4.17777149e-03f, -4.05135504e-03f, -3.92443155e-03f, -3.79707258e-03f, - -3.66923571e-03f, -3.54105471e-03f, -3.41239371e-03f, -3.28339891e-03f, -3.15396381e-03f, -3.02421330e-03f, - -2.89416099e-03f, -2.76374076e-03f, -2.63309928e-03f, -2.50207948e-03f, -2.37087005e-03f, -2.23935784e-03f, - -2.10764005e-03f, -1.97575913e-03f, -1.84358011e-03f, -1.71131142e-03f, -1.57884688e-03f, -1.44627635e-03f, - -1.31358460e-03f, -1.18073196e-03f, -1.04784901e-03f, -9.14871906e-04f, -7.81859931e-04f, -6.48830034e-04f, - -5.15769886e-04f, -3.82672096e-04f, -2.49672038e-04f, -1.16675080e-04f, 1.62704376e-05f, 1.49117572e-04f, - 2.81954398e-04f, 4.14570193e-04f, 5.47098434e-04f, 6.79481456e-04f, 8.11711976e-04f, 9.43739729e-04f, - 1.07558613e-03f, 1.20716175e-03f, 1.33858618e-03f, 1.46973477e-03f, 1.60058857e-03f, 1.73114231e-03f, - 1.86144632e-03f, 1.99140554e-03f, 2.12098881e-03f, 2.25024758e-03f, 2.37914022e-03f, 2.50763828e-03f, - 2.63572379e-03f, 2.76336549e-03f, 2.89058078e-03f, 3.01734895e-03f, 3.14363033e-03f, 3.26943705e-03f, - 3.39472472e-03f, 3.51944909e-03f, 3.64369790e-03f, 3.76734825e-03f, 3.89042886e-03f, 4.01291896e-03f, - 4.13480294e-03f, 4.25608915e-03f, 4.37669890e-03f, 4.49670341e-03f, 4.61598484e-03f, 4.73460335e-03f, - 4.85252415e-03f, 4.96971522e-03f, 5.08616140e-03f, 5.20191212e-03f, 5.31684054e-03f, 5.43105931e-03f, - 5.54439205e-03f, 5.65701650e-03f, 5.76875364e-03f, 5.87967881e-03f, 5.98976951e-03f, 6.09894948e-03f, - 6.20728356e-03f, 6.31468298e-03f, 6.42124453e-03f, 6.52683246e-03f, 6.63152261e-03f, 6.73522887e-03f, - 6.83798041e-03f, 6.93977104e-03f, 7.04054891e-03f, 7.14036693e-03f, 7.23907451e-03f, 7.33692505e-03f, - 7.43362757e-03f, 7.52928864e-03f, 7.62383824e-03f, 7.71734985e-03f, 7.80981527e-03f, 7.90115086e-03f, - 7.99135916e-03f, 8.08044117e-03f, 8.16843147e-03f, 8.25524122e-03f, 8.34091218e-03f, 8.42539250e-03f, - 8.50871701e-03f, 8.59081376e-03f, 8.67177825e-03f, 8.75148985e-03f, 8.82998652e-03f, 8.90726260e-03f, - 8.98327083e-03f, 9.05803730e-03f, 9.13158837e-03f, 9.20384145e-03f, 9.27480549e-03f, 9.34450700e-03f, - 9.41291497e-03f, 9.48004283e-03f, 9.54581456e-03f, 9.61026576e-03f, 9.67343477e-03f, 9.73522743e-03f, - 9.79569875e-03f, 9.85483843e-03f, 9.91257310e-03f, 9.96900125e-03f, 1.00240149e-02f, 1.00776644e-02f, - 1.01299285e-02f, 1.01808079e-02f, 1.02303261e-02f, 1.02783937e-02f, 1.03251008e-02f, 1.03703365e-02f, - 1.04141782e-02f, 1.04566134e-02f, 1.04975959e-02f, 1.05371918e-02f, 1.05752871e-02f, 1.06119921e-02f, - 1.06472056e-02f, 1.06809967e-02f, 1.07133780e-02f, 1.07442603e-02f, 1.07736274e-02f, 1.08016201e-02f, - 1.08281080e-02f, 1.08531457e-02f, 1.08766623e-02f, 1.08987577e-02f, 1.09193496e-02f, 1.09385292e-02f, - 1.09561235e-02f, 1.09723005e-02f, 1.09869712e-02f, 1.10001489e-02f, 1.10119182e-02f, 1.10220981e-02f, - 1.10308807e-02f, 1.10380933e-02f, 1.10438822e-02f, 1.10481722e-02f, 1.10509522e-02f, 1.10523178e-02f, - 1.10520866e-02f, 1.10504429e-02f, 1.10472930e-02f, 1.10426904e-02f, 1.10365783e-02f, 1.10290018e-02f, - 1.10199498e-02f, 1.10094029e-02f, 1.09973924e-02f, 1.09839375e-02f, 1.09689839e-02f, 1.09525723e-02f, - 1.09347161e-02f, 1.09153858e-02f, 1.08946041e-02f, 1.08723586e-02f, 1.08486616e-02f, 1.08235520e-02f, - 1.07970160e-02f, 1.07689771e-02f, 1.07395732e-02f, 1.07086850e-02f, 1.06764429e-02f, 1.06427533e-02f, - 1.06076315e-02f, 1.05711255e-02f, 1.05332178e-02f, 1.04939496e-02f, 1.04532080e-02f, 1.04111772e-02f, - 1.03677212e-02f, 1.03228775e-02f, 1.02767775e-02f, 1.02291914e-02f, 1.01803210e-02f, 1.01301432e-02f, - 1.00785623e-02f, 1.00257436e-02f, 9.97149947e-03f, 9.91604579e-03f, 9.85922503e-03f, 9.80117876e-03f, - 9.74172859e-03f, 9.68113582e-03f, 9.61921636e-03f, 9.55602814e-03f, 9.49165044e-03f, 9.42595769e-03f, - 9.35908219e-03f, 9.29098762e-03f, 9.22166431e-03f, 9.15113775e-03f, 9.07943444e-03f, 9.00656757e-03f, - 8.93254506e-03f, 8.85729490e-03f, 8.78095136e-03f, 8.70344198e-03f, 8.62484904e-03f, 8.54510509e-03f, - 8.46428523e-03f, 8.38232206e-03f, 8.29932172e-03f, 8.21529234e-03f, 8.13012387e-03f, 8.04397488e-03f, - 7.95676942e-03f, 7.86850806e-03f, 7.77930444e-03f, 7.68907061e-03f, 7.59784092e-03f, 7.50569950e-03f, - 7.41252930e-03f, 7.31849294e-03f, 7.22345763e-03f, 7.12754486e-03f, 7.03071792e-03f, 6.93301012e-03f, - 6.83439921e-03f, 6.73491017e-03f, 6.63466284e-03f, 6.53349432e-03f, 6.43157412e-03f, 6.32877004e-03f, - 6.22522578e-03f, 6.12088050e-03f, 6.01578959e-03f, 5.90996324e-03f, 5.80336788e-03f, 5.69607005e-03f, - 5.58803447e-03f, 5.47935023e-03f, 5.36998539e-03f, 5.25995558e-03f, 5.14929527e-03f, 5.03796760e-03f, - 4.92607278e-03f, 4.81354882e-03f, 4.70044109e-03f, 4.58678503e-03f, 4.47258467e-03f, 4.35781524e-03f, - 4.24256011e-03f, 4.12673836e-03f, 4.01047735e-03f, 3.89374680e-03f, 3.77655664e-03f, 3.65892906e-03f, - 3.54083139e-03f, 3.42238075e-03f, 3.30347309e-03f, 3.18426790e-03f, 3.06461984e-03f, 2.94475075e-03f, - 2.82441082e-03f, 2.70384771e-03f, 2.58296470e-03f, 2.46179834e-03f, 2.34036345e-03f, 2.21873244e-03f, - 2.09681557e-03f, 1.97467685e-03f, 1.85241562e-03f, 1.72991055e-03f, 1.60720363e-03f, 1.48447438e-03f, - 1.36153332e-03f, 1.23851343e-03f, 1.11533229e-03f, 9.92106862e-04f, 8.68857670e-04f, 7.45507455e-04f, - 6.22201124e-04f, 4.98771839e-04f, 3.75429872e-04f, 2.52071605e-04f, 1.28763233e-04f, 5.49269327e-06f, - -1.17703733e-04f, -2.40834789e-04f, -3.63827181e-04f, -4.86700564e-04f, -6.09434263e-04f, -7.32059340e-04f, - -8.54474921e-04f, -9.76752997e-04f, -1.09878367e-03f, -1.22061544e-03f, -1.34222929e-03f, -1.46357851e-03f, - -1.58466316e-03f, -1.70548160e-03f, -1.82597759e-03f, -1.94618617e-03f, -2.06599677e-03f, -2.18557383e-03f, - -2.30468989e-03f, -2.42348870e-03f, -2.54185987e-03f, -2.65985699e-03f, -2.77741674e-03f, -2.89453127e-03f, - -3.01118935e-03f, -3.12741629e-03f, -3.24304982e-03f, -3.35831697e-03f, -3.47295848e-03f, -3.58716229e-03f, - -3.70071331e-03f, -3.81376607e-03f, -3.92627672e-03f, -4.03815601e-03f, -4.14941200e-03f, -4.26006922e-03f, - -4.37008502e-03f, -4.47946224e-03f, -4.58817248e-03f, -4.69622097e-03f, -4.80353437e-03f, -4.91017805e-03f, - -5.01606849e-03f, -5.12125275e-03f, -5.22566703e-03f, -5.32935917e-03f, -5.43223335e-03f, -5.53437362e-03f, - -5.63568565e-03f, -5.73615509e-03f, -5.83583097e-03f, -5.93462473e-03f, -6.03260050e-03f, -6.12971713e-03f, - -6.22594088e-03f, -6.32128565e-03f, -6.41569048e-03f, -6.50923293e-03f, -6.60181780e-03f, -6.69347716e-03f, - -6.78417240e-03f, -6.87387734e-03f, -6.96265145e-03f, -7.05045349e-03f, -7.13721712e-03f, -7.22296040e-03f, - -7.30775124e-03f, -7.39145683e-03f, -7.47418626e-03f, -7.55577806e-03f, -7.63635176e-03f, -7.71584184e-03f, - -7.79427228e-03f, -7.87160357e-03f, -7.94784105e-03f, -8.02294718e-03f, -8.09693124e-03f, -8.16980389e-03f, - -8.24152350e-03f, -8.31209813e-03f, -8.38153868e-03f, -8.44979084e-03f, -8.51685801e-03f, -8.58277165e-03f, - -8.64747238e-03f, -8.71100539e-03f, -8.77330980e-03f, -8.83440196e-03f, -8.89429337e-03f, -8.95292523e-03f, - -9.01033101e-03f, -9.06645466e-03f, -9.12141334e-03f, -9.17506449e-03f, -9.22744606e-03f, -9.27860299e-03f, - -9.32841937e-03f, -9.37701580e-03f, -9.42430604e-03f, -9.47028433e-03f, -9.51499397e-03f, -9.55835022e-03f, - -9.60045491e-03f, -9.64121830e-03f, -9.68067011e-03f, -9.71875577e-03f, -9.75560122e-03f, -9.79105176e-03f, - -9.82520162e-03f, -9.85799561e-03f, -9.88943492e-03f, -9.91956463e-03f, -9.94829705e-03f, -9.97571943e-03f, - -1.00017594e-02f, -1.00264337e-02f, -1.00497681e-02f, -1.00717874e-02f, -1.00923180e-02f, -1.01115656e-02f, - -1.01294387e-02f, -1.01459619e-02f, -1.01610659e-02f, -1.01747950e-02f, -1.01872073e-02f, -1.01981811e-02f, - -1.02078131e-02f, -1.02160697e-02f, -1.02229065e-02f, -1.02284367e-02f, -1.02325337e-02f, -1.02353039e-02f, - -1.02366291e-02f, -1.02366263e-02f, -1.02352648e-02f, -1.02324926e-02f, -1.02283465e-02f, -1.02228363e-02f, - -1.02159834e-02f, -1.02077527e-02f, -1.01981137e-02f, -1.01871590e-02f, -1.01748441e-02f, -1.01611539e-02f, - -1.01460611e-02f, -1.01296574e-02f, -1.01119132e-02f, -1.00927879e-02f, -1.00724082e-02f, -1.00505492e-02f, - -1.00274684e-02f, -1.00029773e-02f, -9.97723221e-03f, -9.95007250e-03f, -9.92164914e-03f, -9.89190139e-03f, - -9.86086616e-03f, -9.82848716e-03f, -9.79478811e-03f, -9.75982880e-03f, -9.72358153e-03f, -9.68603976e-03f, - -9.64719517e-03f, -9.60713613e-03f, -9.56572935e-03f, -9.52316946e-03f, -9.47925031e-03f, -9.43412450e-03f, - -9.38775598e-03f, -9.34017062e-03f, -9.29131767e-03f, -9.24129225e-03f, -9.19002748e-03f, -9.13753903e-03f, - -9.08389848e-03f, -9.02904114e-03f, -8.97303493e-03f, -8.91579334e-03f, -8.85744853e-03f, -8.79789114e-03f, - -8.73725141e-03f, -8.67540602e-03f, -8.61249465e-03f, -8.54840752e-03f, -8.48325528e-03f, -8.41695240e-03f, - -8.34960757e-03f, -8.28112976e-03f, -8.21166404e-03f, -8.14103901e-03f, -8.06939851e-03f, -7.99672543e-03f, - -7.92298361e-03f, -7.84828473e-03f, -7.77252338e-03f, -7.69577821e-03f, -7.61804629e-03f, -7.53930939e-03f, - -7.45964387e-03f, -7.37901261e-03f, -7.29742642e-03f, -7.21489987e-03f, -7.13145364e-03f, -7.04713848e-03f, - -6.96187963e-03f, -6.87577534e-03f, -6.78873296e-03f, -6.70087328e-03f, -6.61215083e-03f, -6.52263073e-03f, - -6.43220069e-03f, -6.34103669e-03f, -6.24906338e-03f, -6.15627171e-03f, -6.06276037e-03f, -5.96842060e-03f, - -5.87337406e-03f, -5.77756668e-03f, -5.68110372e-03f, -5.58385329e-03f, -5.48592361e-03f, -5.38735743e-03f, - -5.28806576e-03f, -5.18822114e-03f, -5.08762135e-03f, -4.98645638e-03f, -4.88467045e-03f, -4.78229982e-03f, - -4.67930003e-03f, -4.57577335e-03f, -4.47171046e-03f, -4.36703651e-03f, -4.26193061e-03f, -4.15618588e-03f, - -4.05008934e-03f, -3.94340463e-03f, -3.83633761e-03f, -3.72869066e-03f, -3.62070669e-03f, -3.51227934e-03f, - -3.40344675e-03f, -3.29423996e-03f, -3.18457568e-03f, -3.07461726e-03f, -2.96426731e-03f, -2.85360409e-03f, - -2.74262832e-03f, -2.63133071e-03f, -2.51978129e-03f, -2.40790804e-03f, -2.29581234e-03f, -2.18344723e-03f, - -2.07087846e-03f, -1.95807743e-03f, -1.84506139e-03f, -1.73190093e-03f, -1.61857726e-03f, -1.50507297e-03f, - -1.39145871e-03f, -1.27769307e-03f, -1.16382824e-03f, -1.04988137e-03f, -9.35902828e-04f, -8.21751245e-04f, - -7.07659165e-04f, -5.93510474e-04f, -4.79321632e-04f, -3.65151696e-04f, -2.51018125e-04f, -1.36920271e-04f, - -2.28058050e-05f, 9.11817606e-05f, 2.05131793e-04f, 3.18919622e-04f, 4.32670429e-04f, 5.46262031e-04f, - 6.59766530e-04f, 7.73047268e-04f, 8.86178756e-04f, 9.99145242e-04f, 1.11188462e-03f, 1.22445780e-03f, - 1.33673229e-03f, 1.44881341e-03f, 1.56063133e-03f, 1.67218375e-03f, 1.78336734e-03f, 1.89435305e-03f, - 2.00496380e-03f, 2.11526227e-03f, 2.22517228e-03f, 2.33473892e-03f, 2.44395058e-03f, 2.55276968e-03f, - 2.66118069e-03f, 2.76915663e-03f, 2.87670155e-03f, 2.98378853e-03f, 3.09044007e-03f, 3.19658929e-03f, - 3.30224886e-03f, 3.40742257e-03f, 3.51206513e-03f, 3.61616560e-03f, 3.71973420e-03f, 3.82273307e-03f, - 3.92516708e-03f, 4.02703299e-03f, 4.12826567e-03f, 4.22889498e-03f, 4.32890998e-03f, 4.42823369e-03f, - 4.52701063e-03f, 4.62506007e-03f, 4.72238453e-03f, 4.81910989e-03f, 4.91502092e-03f, 5.01031311e-03f, - 5.10486136e-03f, 5.19864028e-03f, 5.29164755e-03f, 5.38394307e-03f, 5.47546150e-03f, 5.56613899e-03f, - 5.65609652e-03f, 5.74515722e-03f, 5.83344831e-03f, 5.92086673e-03f, 6.00743653e-03f, 6.09318807e-03f, - 6.17806995e-03f, 6.26204886e-03f, 6.34515315e-03f, 6.42733758e-03f, 6.50862831e-03f, 6.58898960e-03f, - 6.66842552e-03f, 6.74690698e-03f, 6.82447499e-03f, 6.90101539e-03f, 6.97665592e-03f, 7.05124186e-03f, - 7.12487412e-03f, 7.19752278e-03f, 7.26916118e-03f, 7.33974614e-03f, 7.40933343e-03f, 7.47789002e-03f, - 7.54540785e-03f, 7.61181633e-03f, 7.67719950e-03f, 7.74157021e-03f, 7.80476163e-03f, 7.86692600e-03f, - 7.92798918e-03f, 7.98796808e-03f, 8.04679149e-03f, 8.10454633e-03f, 8.16114174e-03f, 8.21666471e-03f, - 8.27102261e-03f, 8.32418329e-03f, 8.37626537e-03f, 8.42715696e-03f, 8.47694056e-03f, 8.52552423e-03f, - 8.57289087e-03f, 8.61910472e-03f, 8.66416164e-03f, 8.70802243e-03f, 8.75065284e-03f, 8.79210185e-03f, - 8.83238628e-03f, 8.87139910e-03f, 8.90925914e-03f, 8.94580732e-03f, 8.98123250e-03f, 9.01537217e-03f, - 9.04830555e-03f, 9.07998381e-03f, 9.11044708e-03f, 9.13964632e-03f, 9.16763733e-03f, 9.19434896e-03f, - 9.21981349e-03f, 9.24403573e-03f, 9.26700137e-03f, 9.28866771e-03f, 9.30914399e-03f, 9.32833300e-03f, - 9.34623094e-03f, 9.36288338e-03f, 9.37826651e-03f, 9.39236275e-03f, 9.40524651e-03f, 9.41679087e-03f, - 9.42711734e-03f, 9.43613455e-03f, 9.44389244e-03f, 9.45036568e-03f, 9.45560687e-03f, 9.45955724e-03f, - 9.46221254e-03f, 9.46357460e-03f, 9.46371346e-03f, 9.46258028e-03f, 9.46015625e-03f, 9.45644539e-03f, - 9.45149636e-03f, 9.44525884e-03f, 9.43784647e-03f, 9.42907329e-03f, 9.41905878e-03f, 9.40772151e-03f, - 9.39526002e-03f, 9.38146696e-03f, 9.36645604e-03f, 9.35015225e-03f, 9.33259907e-03f, 9.31383083e-03f, - 9.29382147e-03f, 9.27261717e-03f, 9.25011517e-03f, 9.22643996e-03f, 9.20143081e-03f, 9.17532698e-03f, - 9.14794320e-03f, 9.11935818e-03f, 9.08955648e-03f, 9.05858773e-03f, 9.02636975e-03f, 8.99300313e-03f, - 8.95840842e-03f, 8.92265997e-03f, 8.88573270e-03f, 8.84756990e-03f, 8.80833857e-03f, 8.76790927e-03f, - 8.72630838e-03f, 8.68359771e-03f, 8.63969491e-03f, 8.59472972e-03f, 8.54856165e-03f, 8.50131453e-03f, - 8.45291859e-03f, 8.40346629e-03f, 8.35286945e-03f, 8.30119383e-03f, 8.24845827e-03f, 8.19462016e-03f, - 8.13972474e-03f, 8.08374753e-03f, 8.02673501e-03f, 7.96870161e-03f, 7.90959844e-03f, 7.84947813e-03f, - 7.78833800e-03f, 7.72619071e-03f, 7.66302800e-03f, 7.59887434e-03f, 7.53374924e-03f, 7.46768266e-03f, - 7.40058937e-03f, 7.33260247e-03f, 7.26361924e-03f, 7.19374402e-03f, 7.12289343e-03f, 7.05117211e-03f, - 6.97853814e-03f, 6.90499590e-03f, 6.83058404e-03f, 6.75526147e-03f, 6.67914858e-03f, 6.60210598e-03f, - 6.52427033e-03f, 6.44560148e-03f, 6.36607759e-03f, 6.28579368e-03f, 6.20467561e-03f, 6.12282168e-03f, - 6.04015507e-03f, 5.95671416e-03f, 5.87254280e-03f, 5.78760477e-03f, 5.70197598e-03f, 5.61564811e-03f, - 5.52856124e-03f, 5.44080663e-03f, 5.35238583e-03f, 5.26331420e-03f, 5.17354396e-03f, 5.08314761e-03f, - 4.99213604e-03f, 4.90050834e-03f, 4.80826109e-03f, 4.71539136e-03f, 4.62204253e-03f, 4.52802226e-03f, - 4.43353789e-03f, 4.33844758e-03f, 4.24283869e-03f, 4.14673927e-03f, 4.05014633e-03f, 3.95304303e-03f, - 3.85543521e-03f, 3.75745194e-03f, 3.65897654e-03f, 3.56005936e-03f, 3.46074303e-03f, 3.36099426e-03f, - 3.26087027e-03f, 3.16038118e-03f, 3.05949570e-03f, 2.95831314e-03f, 2.85674809e-03f, 2.75486162e-03f, - 2.65263323e-03f, 2.55018062e-03f, 2.44744153e-03f, 2.34435930e-03f, 2.24110544e-03f, 2.13752712e-03f, - 2.03377687e-03f, 1.92983655e-03f, 1.82571276e-03f, 1.72132832e-03f, 1.61683127e-03f, 1.51213584e-03f, - 1.40731891e-03f, 1.30242814e-03f, 1.19731454e-03f, 1.09220685e-03f, 9.86960492e-04f, 8.81671221e-04f, - 7.76298132e-04f, 6.70871856e-04f, 5.65478060e-04f, 4.60032043e-04f, 3.54600935e-04f, 2.49160352e-04f, - 1.43746187e-04f, 3.84172821e-05f, -6.68705880e-05f, -1.72101488e-04f, -2.77280105e-04f, -3.82268951e-04f, - -4.87196446e-04f, -5.92030253e-04f, -6.96684910e-04f, -8.01139548e-04f, -9.05494967e-04f, -1.00962995e-03f, - -1.11360374e-03f, -1.21731951e-03f, -1.32084501e-03f, -1.42412224e-03f, -1.52711821e-03f, -1.62989487e-03f, - -1.73235206e-03f, -1.83455597e-03f, -1.93640151e-03f, -2.03796357e-03f, -2.13915572e-03f, -2.24007790e-03f, - -2.34061095e-03f, -2.44065434e-03f, -2.54044364e-03f, -2.63979132e-03f, -2.73874549e-03f, -2.83724055e-03f, - -2.93528496e-03f, -3.03292361e-03f, -3.13008318e-03f, -3.22672191e-03f, -3.32289717e-03f, -3.41860188e-03f, - -3.51378896e-03f, -3.60836612e-03f, -3.70247829e-03f, -3.79598944e-03f, -3.88899015e-03f, -3.98136909e-03f, - -4.07319413e-03f, -4.16436668e-03f, -4.25496933e-03f, -4.34489633e-03f, -4.43427944e-03f, -4.52294134e-03f, - -4.61094585e-03f, -4.69829194e-03f, -4.78494252e-03f, -4.87095691e-03f, -4.95618453e-03f, -5.04071995e-03f, - -5.12455634e-03f, -5.20760675e-03f, -5.28995998e-03f, -5.37152673e-03f, -5.45233792e-03f, -5.53234557e-03f, - -5.61156646e-03f, -5.69000439e-03f, -5.76762676e-03f, -5.84442039e-03f, -5.92037756e-03f, -5.99550498e-03f, - -6.06978990e-03f, -6.14319574e-03f, -6.21573500e-03f, -6.28740588e-03f, -6.35819635e-03f, -6.42810698e-03f, - -6.49703988e-03f, -6.56511608e-03f, -6.63225545e-03f, -6.69846591e-03f, -6.76378394e-03f, -6.82805443e-03f, - -6.89144851e-03f, -6.95384773e-03f, -7.01527379e-03f, -7.07575574e-03f, -7.13519441e-03f, -7.19373395e-03f, - -7.25113946e-03f, -7.30766166e-03f, -7.36305668e-03f, -7.41750240e-03f, -7.47092373e-03f, -7.52326905e-03f, - -7.57461739e-03f, -7.62485062e-03f, -7.67409970e-03f, -7.72224865e-03f, -7.76936129e-03f, -7.81538571e-03f, - -7.86034494e-03f, -7.90420420e-03f, -7.94695346e-03f, -7.98866515e-03f, -8.02920485e-03f, -8.06872934e-03f, - -8.10706598e-03f, -8.14434376e-03f, -8.18050759e-03f, -8.21554136e-03f, -8.24941741e-03f, -8.28219148e-03f, - -8.31386146e-03f, -8.34435281e-03f, -8.37376377e-03f, -8.40195082e-03f, -8.42904317e-03f, -8.45491686e-03f, - -8.47974225e-03f, -8.50336339e-03f, -8.52585923e-03f, -8.54714448e-03f, -8.56730422e-03f, -8.58631516e-03f, - -8.60410541e-03f, -8.62077219e-03f, -8.63626514e-03f, -8.65062511e-03f, -8.66374115e-03f, -8.67568607e-03f, - -8.68656465e-03f, -8.69614197e-03f, -8.70462554e-03f, -8.71189834e-03f, -8.71802917e-03f, -8.72297264e-03f, - -8.72674549e-03f, -8.72928460e-03f, -8.73072960e-03f, -8.73097314e-03f, -8.73005228e-03f, -8.72794845e-03f, - -8.72465086e-03f, -8.72021190e-03f, -8.71461593e-03f, -8.70782676e-03f, -8.69989163e-03f, -8.69077721e-03f, - -8.68050146e-03f, -8.66908860e-03f, -8.65649418e-03f, -8.64274264e-03f, -8.62784812e-03f, -8.61184831e-03f, - -8.59461191e-03f, -8.57630122e-03f, -8.55680931e-03f, -8.53618434e-03f, -8.51446498e-03f, -8.49160870e-03f, - -8.46754292e-03f, -8.44244954e-03f, -8.41621511e-03f, -8.38885878e-03f, -8.36036595e-03f, -8.33081112e-03f, - -8.30011274e-03f, -8.26837523e-03f, -8.23548743e-03f, -8.20154831e-03f, -8.16648260e-03f, -8.13045453e-03f, - -8.09319934e-03f, -8.05500837e-03f, -8.01569748e-03f, -7.97534154e-03f, -7.93394442e-03f, -7.89147953e-03f, - -7.84802678e-03f, -7.80354663e-03f, -7.75804295e-03f, -7.71142201e-03f, -7.66395154e-03f, -7.61535795e-03f, - -7.56587432e-03f, -7.51531090e-03f, -7.46380197e-03f, -7.41132993e-03f, -7.35791773e-03f, -7.30349633e-03f, - -7.24820009e-03f, -7.19188510e-03f, -7.13467628e-03f, -7.07653113e-03f, -7.01748386e-03f, -6.95753476e-03f, - -6.89668113e-03f, -6.83493514e-03f, -6.77229083e-03f, -6.70878866e-03f, -6.64442086e-03f, -6.57926021e-03f, - -6.51316507e-03f, -6.44628557e-03f, -6.37857650e-03f, -6.31001176e-03f, -6.24068122e-03f, -6.17052294e-03f, - -6.09963522e-03f, -6.02791526e-03f, -5.95549958e-03f, -5.88221452e-03f, -5.80827868e-03f, -5.73357526e-03f, - -5.65816051e-03f, -5.58203211e-03f, -5.50515340e-03f, -5.42763949e-03f, -5.34940255e-03f, -5.27050663e-03f, - -5.19097884e-03f, -5.11079122e-03f, -5.02995054e-03f, -4.94848436e-03f, -4.86635255e-03f, -4.78374055e-03f, - -4.70043167e-03f, -4.61661870e-03f, -4.53215082e-03f, -4.44720094e-03f, -4.36161911e-03f, -4.27562241e-03f, - -4.18903620e-03f, -4.10195421e-03f, -4.01431559e-03f, -3.92626903e-03f, -3.83769732e-03f, -3.74871693e-03f, - -3.65923290e-03f, -3.56932327e-03f, -3.47902959e-03f, -3.38827324e-03f, -3.29714130e-03f, -3.20561856e-03f, - -3.11374897e-03f, -3.02142859e-03f, -2.92888138e-03f, -2.83592072e-03f, -2.74265319e-03f, -2.64905169e-03f, - -2.55516010e-03f, -2.46102487e-03f, -2.36654580e-03f, -2.27187529e-03f, -2.17689479e-03f, -2.08174953e-03f, - -1.98634854e-03f, -1.89070537e-03f, -1.79493522e-03f, -1.69891338e-03f, -1.60274524e-03f, -1.50642133e-03f, - -1.40998223e-03f, -1.31338487e-03f, -1.21667564e-03f, -1.11984116e-03f, -1.02293030e-03f, -9.25987697e-04f, - -8.28927901e-04f, -7.31795283e-04f, -6.34672133e-04f, -5.37511890e-04f, -4.40291145e-04f, -3.43131711e-04f, - -2.45972130e-04f, -1.48860795e-04f, -5.17406270e-05f, 4.53311103e-05f, 1.42320229e-04f, 2.39192367e-04f, - 3.36023345e-04f, 4.32721034e-04f, 5.29364651e-04f, 6.25786412e-04f, 7.22107902e-04f, 8.18317419e-04f, - 9.14273376e-04f, 1.01008757e-03f, 1.10570935e-03f, 1.20112665e-03f, 1.29631762e-03f, 1.39130322e-03f, - 1.48600215e-03f, 1.58047207e-03f, 1.67466302e-03f, 1.76858659e-03f, 1.86217901e-03f, 1.95549286e-03f, - 2.04846776e-03f, 2.14114593e-03f, 2.23343532e-03f, 2.32536790e-03f, 2.41700761e-03f, 2.50817557e-03f, - 2.59903443e-03f, 2.68940498e-03f, 2.77940767e-03f, 2.86897345e-03f, 2.95810349e-03f, 3.04679526e-03f, - 3.13495387e-03f, 3.22271176e-03f, 3.30995943e-03f, 3.39671825e-03f, 3.48293509e-03f, 3.56866486e-03f, - 3.65387811e-03f, 3.73847918e-03f, 3.82261954e-03f, 3.90610446e-03f, 3.98909811e-03f, 4.07145315e-03f, - 4.15317040e-03f, 4.23437954e-03f, 4.31492688e-03f, 4.39483907e-03f, 4.47410784e-03f, 4.55272124e-03f, - 4.63069619e-03f, 4.70798679e-03f, 4.78461901e-03f, 4.86050121e-03f, 4.93578667e-03f, 5.01028836e-03f, - 5.08407833e-03f, 5.15712177e-03f, 5.22949981e-03f, 5.30109604e-03f, 5.37192362e-03f, 5.44196223e-03f, - 5.51126718e-03f, 5.57980031e-03f, 5.64752101e-03f, 5.71440929e-03f, 5.78053347e-03f, 5.84584620e-03f, - 5.91029791e-03f, 5.97392886e-03f, 6.03672043e-03f, 6.09871035e-03f, 6.15978893e-03f, 6.21998841e-03f, - 6.27935252e-03f, 6.33783847e-03f, 6.39543276e-03f, 6.45211042e-03f, 6.50786569e-03f, 6.56278017e-03f, - 6.61674628e-03f, 6.66981496e-03f, 6.72190235e-03f, 6.77310264e-03f, 6.82335142e-03f, 6.87265116e-03f, - 6.92096044e-03f, 6.96836774e-03f, 7.01476635e-03f, 7.06024077e-03f, 7.10470523e-03f, 7.14817679e-03f, - 7.19071395e-03f, 7.23220754e-03f, 7.27274128e-03f, 7.31222101e-03f, 7.35072377e-03f, 7.38825791e-03f, - 7.42471054e-03f, 7.46019374e-03f, 7.49461943e-03f, 7.52804390e-03f, 7.56042461e-03f, 7.59177395e-03f, - 7.62205801e-03f, 7.65135272e-03f, 7.67952862e-03f, 7.70672477e-03f, 7.73283313e-03f, 7.75787551e-03f, - 7.78192755e-03f, 7.80485512e-03f, 7.82674753e-03f, 7.84757165e-03f, 7.86730188e-03f, 7.88602800e-03f, - 7.90360489e-03f, 7.92014323e-03f, 7.93562725e-03f, 7.95002583e-03f, 7.96333421e-03f, 7.97555463e-03f, - 7.98675573e-03f, 7.99681278e-03f, 8.00585824e-03f, 8.01369714e-03f, 8.02059170e-03f, 8.02635772e-03f, - 8.03101990e-03f, 8.03462175e-03f, 8.03715592e-03f, 8.03855714e-03f, 8.03890219e-03f, 8.03819822e-03f, - 8.03640315e-03f, 8.03349274e-03f, 8.02956412e-03f, 8.02446721e-03f, 8.01844190e-03f, 8.01124046e-03f, - 8.00295982e-03f, 7.99362910e-03f, 7.98327664e-03f, 7.97180012e-03f, 7.95929274e-03f, 7.94569114e-03f, - 7.93104373e-03f, 7.91539758e-03f, 7.89862144e-03f, 7.88081853e-03f, 7.86194564e-03f, 7.84212151e-03f, - 7.82114439e-03f, 7.79918496e-03f, 7.77614665e-03f, 7.75218193e-03f, 7.72709459e-03f, 7.70102592e-03f, - 7.67393197e-03f, 7.64581045e-03f, 7.61668950e-03f, 7.58656642e-03f, 7.55547682e-03f, 7.52329737e-03f, - 7.49020248e-03f, 7.45610907e-03f, 7.42101991e-03f, 7.38500651e-03f, 7.34795564e-03f, 7.31001639e-03f, - 7.27102499e-03f, 7.23116688e-03f, 7.19032081e-03f, 7.14851144e-03f, 7.10582852e-03f, 7.06217560e-03f, - 7.01758606e-03f, 6.97213571e-03f, 6.92574737e-03f, 6.87845587e-03f, 6.83029700e-03f, 6.78121740e-03f, - 6.73126086e-03f, 6.68043806e-03f, 6.62874767e-03f, 6.57620465e-03f, 6.52282203e-03f, 6.46859357e-03f, - 6.41348165e-03f, 6.35763971e-03f, 6.30086464e-03f, 6.24334638e-03f, 6.18501345e-03f, 6.12589055e-03f, - 6.06599953e-03f, 6.00529981e-03f, 5.94383205e-03f, 5.88163078e-03f, 5.81865710e-03f, 5.75493469e-03f, - 5.69051263e-03f, 5.62529726e-03f, 5.55943691e-03f, 5.49285078e-03f, 5.42557318e-03f, 5.35759662e-03f, - 5.28894862e-03f, 5.21961845e-03f, 5.14967718e-03f, 5.07902236e-03f, 5.00777307e-03f, 4.93589358e-03f, - 4.86337959e-03f, 4.79026374e-03f, 4.71655914e-03f, 4.64225913e-03f, 4.56736693e-03f, 4.49191852e-03f, - 4.41592015e-03f, 4.33941786e-03f, 4.26230428e-03f, 4.18471697e-03f, 4.10656069e-03f, 4.02800688e-03f, - 3.94882724e-03f, 3.86927839e-03f, 3.78918689e-03f, 3.70868691e-03f, 3.62772173e-03f, 3.54627413e-03f, - 3.46447368e-03f, 3.38222688e-03f, 3.29955600e-03f, 3.21653175e-03f, 3.13312394e-03f, 3.04932426e-03f, - 2.96518949e-03f, 2.88066148e-03f, 2.79585301e-03f, 2.71071004e-03f, 2.62527221e-03f, 2.53948765e-03f, - 2.45341420e-03f, 2.36712360e-03f, 2.28053588e-03f, 2.19369750e-03f, 2.10661847e-03f, 2.01932540e-03f, - 1.93179391e-03f, 1.84404984e-03f, 1.75615317e-03f, 1.66801249e-03f, 1.57977340e-03f, 1.49134159e-03f, - 1.40278306e-03f, 1.31406759e-03f, 1.22520394e-03f, 1.13631096e-03f, 1.04725512e-03f, 9.58151831e-04f, - 8.68957980e-04f, 7.79690348e-04f, 6.90411775e-04f, 6.01048332e-04f, 5.11707324e-04f, 4.22338456e-04f, - 3.32968205e-04f, 2.43591574e-04f, 1.54231210e-04f, 6.49406484e-05f, -2.43003833e-05f, -1.13519432e-04f, - -2.02661333e-04f, -2.91714434e-04f, -3.80643210e-04f, -4.69504354e-04f, -5.58228260e-04f, -6.46754098e-04f, - -7.35265039e-04f, -8.23573380e-04f, -9.11717737e-04f, -9.99630294e-04f, -1.08741401e-03f, -1.17496214e-03f, - -1.26236275e-03f, -1.34946631e-03f, -1.43636382e-03f, -1.52296690e-03f, -1.60939958e-03f, -1.69550166e-03f, - -1.78134463e-03f, -1.86685695e-03f, -1.95210457e-03f, -2.03702731e-03f, -2.12163116e-03f, -2.20586991e-03f, - -2.28979077e-03f, -2.37334878e-03f, -2.45653794e-03f, -2.53931318e-03f, -2.62171489e-03f, -2.70369093e-03f, - -2.78528547e-03f, -2.86643716e-03f, -2.94718304e-03f, -3.02745372e-03f, -3.10723382e-03f, -3.18661822e-03f, - -3.26549424e-03f, -3.34388033e-03f, -3.42178574e-03f, -3.49914035e-03f, -3.57600852e-03f, -3.65233396e-03f, - -3.72815595e-03f, -3.80335919e-03f, -3.87805977e-03f, -3.95218697e-03f, -4.02570016e-03f, -4.09871175e-03f, - -4.17103489e-03f, -4.24279129e-03f, -4.31392121e-03f, -4.38445858e-03f, -4.45433869e-03f, -4.52359185e-03f, - -4.59214567e-03f, -4.66012638e-03f, -4.72735707e-03f, -4.79394597e-03f, -4.85982259e-03f, -4.92504343e-03f, - -4.98953648e-03f, -5.05335056e-03f, -5.11643259e-03f, -5.17874830e-03f, -5.24036316e-03f, -5.30122211e-03f, - -5.36137411e-03f, -5.42080134e-03f, -5.47930978e-03f, -5.53713211e-03f, -5.59415756e-03f, -5.65045341e-03f, - -5.70590780e-03f, -5.76056834e-03f, -5.81445524e-03f, -5.86744896e-03f, -5.91969296e-03f, -5.97105918e-03f, - -6.02164490e-03f, -6.07133160e-03f, -6.12023451e-03f, -6.16823205e-03f, -6.21538276e-03f, -6.26168188e-03f, - -6.30711432e-03f, -6.35163483e-03f, -6.39534000e-03f, -6.43808862e-03f, -6.48003697e-03f, -6.52100928e-03f, - -6.56103962e-03f, -6.60027058e-03f, -6.63856097e-03f, -6.67590341e-03f, -6.71233758e-03f, -6.74784228e-03f, - -6.78244396e-03f, -6.81610644e-03f, -6.84882235e-03f, -6.88060553e-03f, -6.91141703e-03f, -6.94134903e-03f, - -6.97024000e-03f, -6.99822099e-03f, -7.02524604e-03f, -7.05132752e-03f, -7.07644596e-03f, -7.10053329e-03f, - -7.12372614e-03f, -7.14590740e-03f, -7.16713607e-03f, -7.18736051e-03f, -7.20665279e-03f, -7.22497108e-03f, - -7.24224453e-03f, -7.25858092e-03f, -7.27388709e-03f, -7.28824267e-03f, -7.30161645e-03f, -7.31400518e-03f, - -7.32538883e-03f, -7.33577948e-03f, -7.34516936e-03f, -7.35358626e-03f, -7.36102782e-03f, -7.36742447e-03f, - -7.37289457e-03f, -7.37728383e-03f, -7.38075633e-03f, -7.38319493e-03f, -7.38466050e-03f, -7.38512679e-03f, - -7.38460887e-03f, -7.38310437e-03f, -7.38057681e-03f, -7.37711634e-03f, -7.37257336e-03f, -7.36712558e-03f, - -7.36070044e-03f, -7.35323751e-03f, -7.34483248e-03f, -7.33538107e-03f, -7.32505799e-03f, -7.31365115e-03f, - -7.30135112e-03f, -7.28803252e-03f, -7.27374334e-03f, -7.25850386e-03f, -7.24229530e-03f, -7.22510084e-03f, - -7.20701672e-03f, -7.18791076e-03f, -7.16788522e-03f, -7.14686424e-03f, -7.12494825e-03f, -7.10208138e-03f, - -7.07823041e-03f, -7.05350432e-03f, -7.02784588e-03f, -7.00117118e-03f, -6.97368700e-03f, -6.94516825e-03f, - -6.91587446e-03f, -6.88555610e-03f, -6.85441458e-03f, -6.82231880e-03f, -6.78929164e-03f, -6.75548326e-03f, - -6.72069046e-03f, -6.68510950e-03f, -6.64854379e-03f, -6.61117589e-03f, -6.57292872e-03f, -6.53386546e-03f, - -6.49387805e-03f, -6.45308763e-03f, -6.41146189e-03f, -6.36894183e-03f, -6.32565673e-03f, -6.28154550e-03f, - -6.23660971e-03f, -6.19086753e-03f, -6.14430773e-03f, -6.09695676e-03f, -6.04883982e-03f, -5.99991954e-03f, - -5.95021759e-03f, -5.89977381e-03f, -5.84854641e-03f, -5.79657988e-03f, -5.74386296e-03f, -5.69040645e-03f, - -5.63622380e-03f, -5.58134611e-03f, -5.52570227e-03f, -5.46937862e-03f, -5.41238679e-03f, -5.35464854e-03f, - -5.29624047e-03f, -5.23716773e-03f, -5.17744828e-03f, -5.11704215e-03f, -5.05603244e-03f, -4.99432761e-03f, - -4.93200171e-03f, -4.86908632e-03f, -4.80554789e-03f, -4.74139009e-03f, -4.67663640e-03f, -4.61131309e-03f, - -4.54538437e-03f, -4.47891071e-03f, -4.41187925e-03f, -4.34426148e-03f, -4.27617708e-03f, -4.20751027e-03f, - -4.13831105e-03f, -4.06862543e-03f, -3.99844323e-03f, -3.92773789e-03f, -3.85657272e-03f, -3.78495497e-03f, - -3.71283872e-03f, -3.64029394e-03f, -3.56727234e-03f, -3.49385325e-03f, -3.42000176e-03f, -3.34572774e-03f, - -3.27107354e-03f, -3.19605244e-03f, -3.12057504e-03f, -3.04477671e-03f, -2.96863667e-03f, -2.89210669e-03f, - -2.81521376e-03f, -2.73807998e-03f, -2.66050707e-03f, -2.58273040e-03f, -2.50459473e-03f, -2.42621942e-03f, - -2.34759673e-03f, -2.26863340e-03f, -2.18940134e-03f, -2.11000306e-03f, -2.03033447e-03f, -1.95046953e-03f, - -1.87032740e-03f, -1.79005967e-03f, -1.70954622e-03f, -1.62888539e-03f, -1.54807312e-03f, -1.46706823e-03f, - -1.38597533e-03f, -1.30467290e-03f, -1.22329765e-03f, -1.14178788e-03f, -1.06019690e-03f, -9.78491058e-04f, - -8.96714846e-04f, -8.14853668e-04f, -7.33003935e-04f, -6.51048804e-04f, -5.69056295e-04f, -4.87054646e-04f, - -4.05060510e-04f, -3.23000075e-04f, -2.41043064e-04f, -1.59064692e-04f, -7.70706971e-05f, 4.81155704e-06f, - 8.66880517e-05f, 1.68484450e-04f, 2.50201446e-04f, 3.31863368e-04f, 4.13364425e-04f, 4.94793144e-04f, - 5.76109921e-04f, 6.57321807e-04f, 7.38330091e-04f, 8.19235621e-04f, 8.99965817e-04f, 9.80503586e-04f, - 1.06085765e-03f, 1.14104110e-03f, 1.22106206e-03f, 1.30082379e-03f, 1.38028980e-03f, 1.45962474e-03f, - 1.53865541e-03f, 1.61747045e-03f, 1.69599504e-03f, 1.77421280e-03f, 1.85216771e-03f, 1.92984336e-03f, - 2.00717079e-03f, 2.08422432e-03f, 2.16095598e-03f, 2.23727185e-03f, 2.31328887e-03f, 2.38893016e-03f, - 2.46423008e-03f, 2.53912867e-03f, 2.61363788e-03f, 2.68774350e-03f, 2.76150713e-03f, 2.83473965e-03f, - 2.90761432e-03f, 2.98003182e-03f, 3.05201777e-03f, 3.12353217e-03f, 3.19459822e-03f, 3.26517143e-03f, - 3.33528934e-03f, 3.40490494e-03f, 3.47396606e-03f, 3.54253099e-03f, 3.61064749e-03f, 3.67816852e-03f, - 3.74523048e-03f, 3.81163602e-03f, 3.87754762e-03f, 3.94291340e-03f, 4.00766738e-03f, 4.07186051e-03f, - 4.13546264e-03f, 4.19848593e-03f, 4.26086978e-03f, 4.32268827e-03f, 4.38380655e-03f, 4.44439637e-03f, - 4.50427679e-03f, 4.56354041e-03f, 4.62214808e-03f, 4.68012938e-03f, 4.73739876e-03f, 4.79401568e-03f, - 4.84995829e-03f, 4.90521046e-03f, 4.95975711e-03f, 5.01362684e-03f, 5.06674514e-03f, 5.11919728e-03f, - 5.17089150e-03f, 5.22189305e-03f, 5.27213195e-03f, 5.32162877e-03f, 5.37040442e-03f, 5.41840285e-03f, - 5.46565316e-03f, 5.51215400e-03f, 5.55784948e-03f, 5.60281526e-03f, 5.64697681e-03f, 5.69034256e-03f, - 5.73292565e-03f, 5.77470952e-03f, 5.81566220e-03f, 5.85585947e-03f, 5.89524720e-03f, 5.93377900e-03f, - 5.97152160e-03f, 6.00837099e-03f, 6.04445351e-03f, 6.07966972e-03f, 6.11412241e-03f, 6.14767546e-03f, - 6.18036207e-03f, 6.21220207e-03f, 6.24317528e-03f, 6.27336747e-03f, 6.30262177e-03f, 6.33104032e-03f, - 6.35860890e-03f, 6.38526493e-03f, 6.41105467e-03f, 6.43599252e-03f, 6.46003085e-03f, 6.48320494e-03f, - 6.50547915e-03f, 6.52686066e-03f, 6.54735808e-03f, 6.56695176e-03f, 6.58568695e-03f, 6.60348202e-03f, - 6.62043741e-03f, 6.63641866e-03f, 6.65154072e-03f, 6.66573396e-03f, 6.67906604e-03f, 6.69148760e-03f, - 6.70297173e-03f, 6.71357165e-03f, 6.72322637e-03f, 6.73204199e-03f, 6.73993119e-03f, 6.74685610e-03f, - 6.75286273e-03f, 6.75801665e-03f, 6.76222651e-03f, 6.76558716e-03f, 6.76798237e-03f, 6.76949037e-03f, - 6.76999526e-03f, 6.76975803e-03f, 6.76846258e-03f, 6.76638806e-03f, 6.76328910e-03f, 6.75934022e-03f, - 6.75450254e-03f, 6.74873935e-03f, 6.74206969e-03f, 6.73450274e-03f, 6.72604747e-03f, 6.71667495e-03f, - 6.70641368e-03f, 6.69526961e-03f, 6.68323226e-03f, 6.67030022e-03f, 6.65648470e-03f, 6.64180312e-03f, - 6.62620835e-03f, 6.60972266e-03f, 6.59240024e-03f, 6.57420686e-03f, 6.55506698e-03f, 6.53521317e-03f, - 6.51431592e-03f, 6.49267138e-03f, 6.47012753e-03f, 6.44673297e-03f, 6.42252856e-03f, 6.39738808e-03f, - 6.37152299e-03f, 6.34473150e-03f, 6.31715005e-03f, 6.28868321e-03f, 6.25948298e-03f, 6.22937671e-03f, - 6.19850198e-03f, 6.16679434e-03f, 6.13428041e-03f, 6.10098609e-03f, 6.06686931e-03f, 6.03195241e-03f, - 5.99626344e-03f, 5.95980987e-03f, 5.92254357e-03f, 5.88456144e-03f, 5.84577569e-03f, 5.80619303e-03f, - 5.76593749e-03f, 5.72489371e-03f, 5.68310872e-03f, 5.64057805e-03f, 5.59736118e-03f, 5.55337081e-03f, - 5.50868679e-03f, 5.46328893e-03f, 5.41717048e-03f, 5.37039683e-03f, 5.32290333e-03f, 5.27473801e-03f, - 5.22586072e-03f, 5.17636297e-03f, 5.12616606e-03f, 5.07535140e-03f, 5.02386460e-03f, 4.97177084e-03f, - 4.91898073e-03f, 4.86561455e-03f, 4.81162647e-03f, 4.75696005e-03f, 4.70180685e-03f, 4.64595257e-03f, - 4.58959018e-03f, 4.53257667e-03f, 4.47505987e-03f, 4.41693154e-03f, 4.35830268e-03f, 4.29909201e-03f, - 4.23934183e-03f, 4.17906470e-03f, 4.11822938e-03f, 4.05693187e-03f, 3.99514269e-03f, 3.93281401e-03f, - 3.87001497e-03f, 3.80671893e-03f, 3.74295373e-03f, 3.67879605e-03f, 3.61415550e-03f, 3.54900916e-03f, - 3.48349806e-03f, 3.41752684e-03f, 3.35115190e-03f, 3.28437665e-03f, 3.21717874e-03f, 3.14962775e-03f, - 3.08171488e-03f, 3.01336047e-03f, 2.94469365e-03f, 2.87564710e-03f, 2.80632031e-03f, 2.73661361e-03f, - 2.66659196e-03f, 2.59630078e-03f, 2.52562855e-03f, 2.45475261e-03f, 2.38351644e-03f, 2.31202381e-03f, - 2.24029128e-03f, 2.16829049e-03f, 2.09607048e-03f, 2.02357818e-03f, 1.95088222e-03f, 1.87798833e-03f, - 1.80487308e-03f, 1.73155539e-03f, 1.65803784e-03f, 1.58440519e-03f, 1.51058295e-03f, 1.43656435e-03f, - 1.36244585e-03f, 1.28818233e-03f, 1.21380326e-03f, 1.13930075e-03f, 1.06469297e-03f, 9.89959325e-04f, - 9.15191435e-04f, 8.40388397e-04f, 7.65399494e-04f, 6.90451123e-04f, 6.15454148e-04f, 5.40384964e-04f, - 4.65309339e-04f, 3.90224171e-04f, 3.15117654e-04f, 2.40096312e-04f, 1.64980038e-04f, 8.99606985e-05f, - 1.49316259e-05f, -5.99914065e-05f, -1.34904109e-04f, -2.09725280e-04f, -2.84453617e-04f, -3.59188964e-04f, - -4.33676564e-04f, -5.08159251e-04f, -5.82468991e-04f, -6.56714390e-04f, -7.30789755e-04f, -8.04710024e-04f, - -8.78486503e-04f, -9.52103055e-04f, -1.02552961e-03f, -1.09876690e-03f, -1.17179814e-03f, -1.24464787e-03f, - -1.31727868e-03f, -1.38970504e-03f, -1.46184041e-03f, -1.53378991e-03f, -1.60545365e-03f, -1.67684738e-03f, - -1.74799855e-03f, -1.81884959e-03f, -1.88938971e-03f, -1.95965282e-03f, -2.02963501e-03f, -2.09925701e-03f, - -2.16856276e-03f, -2.23753306e-03f, -2.30616581e-03f, -2.37440000e-03f, -2.44233377e-03f, -2.50986136e-03f, - -2.57701421e-03f, -2.64378088e-03f, -2.71013201e-03f, -2.77606628e-03f, -2.84161735e-03f, -2.90677323e-03f, - -2.97142810e-03f, -3.03565657e-03f, -3.09945853e-03f, -3.16277679e-03f, -3.22561812e-03f, -3.28803098e-03f, - -3.34992888e-03f, -3.41134498e-03f, -3.47226884e-03f, -3.53267618e-03f, -3.59261352e-03f, -3.65192223e-03f, - -3.71078911e-03f, -3.76911823e-03f, -3.82686170e-03f, -3.88409370e-03f, -3.94075005e-03f, -3.99681846e-03f, - -4.05232546e-03f, -4.10726531e-03f, -4.16160122e-03f, -4.21533927e-03f, -4.26852693e-03f, -4.32107543e-03f, - -4.37299921e-03f, -4.42426259e-03f, -4.47492334e-03f, -4.52504420e-03f, -4.57441138e-03f, -4.62316251e-03f, - -4.67124668e-03f, -4.71871350e-03f, -4.76545667e-03f, -4.81159969e-03f, -4.85705301e-03f, -4.90177171e-03f, - -4.94583838e-03f, -4.98920484e-03f, -5.03188211e-03f, -5.07387286e-03f, -5.11509473e-03f, -5.15565967e-03f, - -5.19545990e-03f, -5.23458573e-03f, -5.27293812e-03f, -5.31062125e-03f, -5.34748742e-03f, -5.38365374e-03f, - -5.41910373e-03f, -5.45372123e-03f, -5.48766366e-03f, -5.52078731e-03f, -5.55317158e-03f, -5.58480681e-03f, - -5.61564434e-03f, -5.64572815e-03f, -5.67504049e-03f, -5.70354124e-03f, -5.73127415e-03f, -5.75819592e-03f, - -5.78436525e-03f, -5.80973766e-03f, -5.83430838e-03f, -5.85805070e-03f, -5.88100437e-03f, -5.90320453e-03f, - -5.92453387e-03f, -5.94506695e-03f, -5.96478046e-03f, -5.98373915e-03f, -6.00182594e-03f, -6.01907784e-03f, - -6.03555767e-03f, -6.05119873e-03f, -6.06604565e-03f, -6.08000223e-03f, -6.09321553e-03f, -6.10553918e-03f, - -6.11704485e-03f, -6.12774605e-03f, -6.13760745e-03f, -6.14667949e-03f, -6.15480131e-03f, -6.16221051e-03f, - -6.16873305e-03f, -6.17443258e-03f, -6.17933439e-03f, -6.18332160e-03f, -6.18656710e-03f, -6.18890387e-03f, - -6.19045347e-03f, -6.19120408e-03f, -6.19103313e-03f, -6.19010217e-03f, -6.18831357e-03f, -6.18573928e-03f, - -6.18224767e-03f, -6.17800002e-03f, -6.17291677e-03f, -6.16699269e-03f, -6.16026478e-03f, -6.15264992e-03f, - -6.14426906e-03f, -6.13509396e-03f, -6.12508319e-03f, -6.11424018e-03f, -6.10257024e-03f, -6.09010124e-03f, - -6.07688245e-03f, -6.06275869e-03f, -6.04789318e-03f, -6.03219941e-03f, -6.01573664e-03f, -5.99844004e-03f, - -5.98037686e-03f, -5.96153958e-03f, -5.94184661e-03f, -5.92147812e-03f, -5.90021142e-03f, -5.87823821e-03f, - -5.85546783e-03f, -5.83192709e-03f, -5.80764744e-03f, -5.78255147e-03f, -5.75673806e-03f, -5.73016369e-03f, - -5.70281692e-03f, -5.67473379e-03f, -5.64592198e-03f, -5.61639128e-03f, -5.58610666e-03f, -5.55503508e-03f, - -5.52327278e-03f, -5.49083250e-03f, -5.45768406e-03f, -5.42377994e-03f, -5.38917462e-03f, -5.35384705e-03f, - -5.31789012e-03f, -5.28119039e-03f, -5.24384206e-03f, -5.20578943e-03f, -5.16706850e-03f, -5.12766198e-03f, - -5.08767140e-03f, -5.04692322e-03f, -5.00560455e-03f, -4.96357305e-03f, -4.92096438e-03f, -4.87766771e-03f, - -4.83382347e-03f, -4.78930850e-03f, -4.74416521e-03f, -4.69844488e-03f, -4.65210607e-03f, -4.60518610e-03f, - -4.55769887e-03f, -4.50959696e-03f, -4.46093501e-03f, -4.41168704e-03f, -4.36193192e-03f, -4.31156706e-03f, - -4.26070274e-03f, -4.20929427e-03f, -4.15733621e-03f, -4.10487918e-03f, -4.05186830e-03f, -3.99835790e-03f, - -3.94436516e-03f, -3.88990306e-03f, -3.83491079e-03f, -3.77947006e-03f, -3.72353451e-03f, -3.66713483e-03f, - -3.61032748e-03f, -3.55302675e-03f, -3.49532632e-03f, -3.43714477e-03f, -3.37857653e-03f, -3.31959981e-03f, - -3.26017175e-03f, -3.20040945e-03f, -3.14023771e-03f, -3.07966269e-03f, -3.01872063e-03f, -2.95741401e-03f, - -2.89576459e-03f, -2.83376659e-03f, -2.77143885e-03f, -2.70873486e-03f, -2.64579444e-03f, -2.58247156e-03f, - -2.51884330e-03f, -2.45495829e-03f, -2.39076499e-03f, -2.32629477e-03f, -2.26159973e-03f, -2.19653335e-03f, - -2.13132448e-03f, -2.06582574e-03f, -2.00013308e-03f, -1.93418965e-03f, -1.86801063e-03f, -1.80163225e-03f, - -1.73508853e-03f, -1.66834048e-03f, -1.60137127e-03f, -1.53430181e-03f, -1.46704872e-03f, -1.39962747e-03f, - -1.33209403e-03f, -1.26434815e-03f, -1.19660977e-03f, -1.12866746e-03f, -1.06064315e-03f, -9.92466023e-04f, - -9.24283244e-04f, -8.56009538e-04f, -7.87633600e-04f, -7.19192624e-04f, -6.50742038e-04f, -5.82240946e-04f, - -5.13691194e-04f, -4.45081779e-04f, -3.76542051e-04f, -3.07943330e-04f, -2.39366547e-04f, -1.70826280e-04f, - -1.02259037e-04f, -3.38032528e-05f, 3.47414961e-05f, 1.03114741e-04f, 1.71498262e-04f, 2.39759560e-04f, - 3.07963321e-04f, 3.76078686e-04f, 4.44134329e-04f, 5.12030130e-04f, 5.79824393e-04f, 6.47529184e-04f, - 7.15080753e-04f, 7.82455076e-04f, 8.49704586e-04f, 9.16819317e-04f, 9.83757692e-04f, 1.05053262e-03f, - 1.11704942e-03f, 1.18344600e-03f, 1.24960266e-03f, 1.31552764e-03f, 1.38128367e-03f, 1.44675429e-03f, - 1.51205804e-03f, 1.57705154e-03f, 1.64185476e-03f, 1.70628171e-03f, 1.77053919e-03f, 1.83448410e-03f, - 1.89812449e-03f, 1.96146602e-03f, 2.02457936e-03f, 2.08728367e-03f, 2.14966772e-03f, 2.21174984e-03f, - 2.27351554e-03f, 2.33491715e-03f, 2.39592908e-03f, 2.45662574e-03f, 2.51689425e-03f, 2.57684930e-03f, - 2.63639649e-03f, 2.69555418e-03f, 2.75428407e-03f, 2.81262678e-03f, 2.87053774e-03f, 2.92805087e-03f, - 2.98509337e-03f, 3.04174500e-03f, 3.09789554e-03f, 3.15361170e-03f, 3.20890122e-03f, 3.26365267e-03f, - 3.31801054e-03f, 3.37185236e-03f, 3.42517598e-03f, 3.47802913e-03f, 3.53040521e-03f, 3.58222742e-03f, - 3.63354183e-03f, 3.68437288e-03f, 3.73463414e-03f, 3.78436964e-03f, 3.83356462e-03f, 3.88220267e-03f, - 3.93030568e-03f, 3.97785512e-03f, 4.02482950e-03f, 4.07120244e-03f, 4.11700982e-03f, 4.16226812e-03f, - 4.20692653e-03f, 4.25097978e-03f, 4.29439981e-03f, 4.33727795e-03f, 4.37951808e-03f, 4.42110128e-03f, - 4.46211946e-03f, 4.50246674e-03f, 4.54224331e-03f, 4.58130070e-03f, 4.61978975e-03f, 4.65762450e-03f, - 4.69479205e-03f, 4.73129961e-03f, 4.76711262e-03f, 4.80230638e-03f, 4.83680790e-03f, 4.87069120e-03f, - 4.90387685e-03f, 4.93632439e-03f, 4.96814534e-03f, 4.99926256e-03f, 5.02970070e-03f, 5.05938557e-03f, - 5.08843843e-03f, 5.11680096e-03f, 5.14438989e-03f, 5.17130536e-03f, 5.19747954e-03f, 5.22299522e-03f, - 5.24776725e-03f, 5.27177987e-03f, 5.29514205e-03f, 5.31771118e-03f, 5.33960722e-03f, 5.36073806e-03f, - 5.38113434e-03f, 5.40078966e-03f, 5.41973689e-03f, 5.43793118e-03f, 5.45537141e-03f, 5.47205214e-03f, - 5.48802240e-03f, 5.50325880e-03f, 5.51768673e-03f, 5.53139476e-03f, 5.54439754e-03f, 5.55657423e-03f, - 5.56805323e-03f, 5.57871965e-03f, 5.58866945e-03f, 5.59788424e-03f, 5.60627972e-03f, 5.61396660e-03f, - 5.62089205e-03f, 5.62704322e-03f, 5.63243816e-03f, 5.63706886e-03f, 5.64095943e-03f, 5.64405355e-03f, - 5.64647038e-03f, 5.64803898e-03f, 5.64888946e-03f, 5.64896391e-03f, 5.64827028e-03f, 5.64685012e-03f, - 5.64467524e-03f, 5.64170526e-03f, 5.63804204e-03f, 5.63354075e-03f, 5.62838515e-03f, 5.62242947e-03f, - 5.61569734e-03f, 5.60826832e-03f, 5.60004607e-03f, 5.59111002e-03f, 5.58141817e-03f, 5.57096240e-03f, - 5.55979727e-03f, 5.54790082e-03f, 5.53523579e-03f, 5.52185737e-03f, 5.50776560e-03f, 5.49292680e-03f, - 5.47734269e-03f, 5.46104805e-03f, 5.44401445e-03f, 5.42628080e-03f, 5.40787557e-03f, 5.38870755e-03f, - 5.36880665e-03f, 5.34826010e-03f, 5.32694568e-03f, 5.30501695e-03f, 5.28230327e-03f, 5.25893962e-03f, - 5.23487266e-03f, 5.21011460e-03f, 5.18473198e-03f, 5.15860454e-03f, 5.13181473e-03f, 5.10440232e-03f, - 5.07626009e-03f, 5.04750859e-03f, 5.01804368e-03f, 4.98797373e-03f, 4.95723405e-03f, 4.92586391e-03f, - 4.89384870e-03f, 4.86119396e-03f, 4.82793161e-03f, 4.79399832e-03f, 4.75948262e-03f, 4.72433245e-03f, - 4.68859793e-03f, 4.65223726e-03f, 4.61528319e-03f, 4.57775635e-03f, 4.53961040e-03f, 4.50092166e-03f, - 4.46159591e-03f, 4.42173866e-03f, 4.38129061e-03f, 4.34031189e-03f, 4.29877409e-03f, 4.25669825e-03f, - 4.21404265e-03f, 4.17090599e-03f, 4.12716560e-03f, 4.08295190e-03f, 4.03822663e-03f, 3.99295742e-03f, - 3.94723671e-03f, 3.90093027e-03f, 3.85425137e-03f, 3.80695336e-03f, 3.75927790e-03f, 3.71112412e-03f, - 3.66247207e-03f, 3.61338104e-03f, 3.56381443e-03f, 3.51381513e-03f, 3.46339110e-03f, 3.41253551e-03f, - 3.36123867e-03f, 3.30952219e-03f, 3.25746224e-03f, 3.20491683e-03f, 3.15204370e-03f, 3.09872425e-03f, - 3.04509203e-03f, 2.99104739e-03f, 2.93665077e-03f, 2.88187653e-03f, 2.82679926e-03f, 2.77133635e-03f, - 2.71554400e-03f, 2.65943304e-03f, 2.60300325e-03f, 2.54628705e-03f, 2.48924637e-03f, 2.43189957e-03f, - 2.37435390e-03f, 2.31638241e-03f, 2.25825783e-03f, 2.19981408e-03f, 2.14112104e-03f, 2.08221217e-03f, - 2.02303645e-03f, 1.96363577e-03f, 1.90397837e-03f, 1.84419150e-03f, 1.78411018e-03f, 1.72391632e-03f, - 1.66345299e-03f, 1.60287561e-03f, 1.54209593e-03f, 1.48113460e-03f, 1.42003292e-03f, 1.35879291e-03f, - 1.29739298e-03f, 1.23588236e-03f, 1.17420764e-03f, 1.11243994e-03f, 1.05058277e-03f, 9.88634601e-04f, - 9.26588340e-04f, 8.64440827e-04f, 8.02250074e-04f, 7.39970744e-04f, 6.77627250e-04f, 6.15287312e-04f, - 5.52850576e-04f, 4.90408360e-04f, 4.27941791e-04f, 3.65454039e-04f, 3.02955364e-04f, 2.40450906e-04f, - 1.78008646e-04f, 1.15564671e-04f, 5.31328680e-05f, -9.26072038e-06f, -7.16197381e-05f, -1.33885772e-04f, - -1.96120802e-04f, -2.58306671e-04f, -3.20361395e-04f, -3.82401440e-04f, -4.44246073e-04f, -5.06091775e-04f, - -5.67752117e-04f, -6.29353418e-04f, -6.90774766e-04f, -7.52089070e-04f, -8.13263206e-04f, -8.74249923e-04f, - -9.35114930e-04f, -9.95784509e-04f, -1.05630898e-03f, -1.11662847e-03f, -1.17677895e-03f, -1.23670237e-03f, - -1.29641408e-03f, -1.35593327e-03f, -1.41523866e-03f, -1.47426098e-03f, -1.53313063e-03f, -1.59164224e-03f, - -1.64999704e-03f, -1.70802952e-03f, -1.76583242e-03f, -1.82333748e-03f, -1.88056380e-03f, -1.93750357e-03f, - -1.99409428e-03f, -2.05045162e-03f, -2.10644954e-03f, -2.16216512e-03f, -2.21748612e-03f, -2.27251127e-03f, - -2.32717490e-03f, -2.38157499e-03f, -2.43552575e-03f, -2.48911988e-03f, -2.54237111e-03f, -2.59523199e-03f, - -2.64765041e-03f, -2.69978913e-03f, -2.75144057e-03f, -2.80275844e-03f, -2.85360151e-03f, -2.90407056e-03f, - -2.95406701e-03f, -3.00367599e-03f, -3.05285567e-03f, -3.10151156e-03f, -3.14980704e-03f, -3.19761298e-03f, - -3.24498149e-03f, -3.29183255e-03f, -3.33821688e-03f, -3.38413745e-03f, -3.42960140e-03f, -3.47453362e-03f, - -3.51899161e-03f, -3.56291712e-03f, -3.60633830e-03f, -3.64928351e-03f, -3.69164277e-03f, -3.73357831e-03f, - -3.77492452e-03f, -3.81571706e-03f, -3.85596469e-03f, -3.89571985e-03f, -3.93484392e-03f, -3.97353034e-03f, - -4.01155791e-03f, -4.04906442e-03f, -4.08600902e-03f, -4.12231710e-03f, -4.15814817e-03f, -4.19327914e-03f, - -4.22788903e-03f, -4.26195629e-03f, -4.29535194e-03f, -4.32816631e-03f, -4.36037257e-03f, -4.39196903e-03f, - -4.42299560e-03f, -4.45336662e-03f, -4.48311186e-03f, -4.51226211e-03f, -4.54083216e-03f, -4.56865564e-03f, - -4.59590024e-03f, -4.62253837e-03f, -4.64851302e-03f, -4.67389011e-03f, -4.69858646e-03f, -4.72261810e-03f, - -4.74602696e-03f, -4.76876836e-03f, -4.79082996e-03f, -4.81223745e-03f, -4.83304233e-03f, -4.85314100e-03f, - -4.87259652e-03f, -4.89137257e-03f, -4.90948172e-03f, -4.92691042e-03f, -4.94367052e-03f, -4.95977781e-03f, - -4.97517903e-03f, -4.98991851e-03f, -5.00396127e-03f, -5.01733934e-03f, -5.03002546e-03f, -5.04202585e-03f, - -5.05337327e-03f, -5.06399625e-03f, -5.07392209e-03f, -5.08320787e-03f, -5.09178812e-03f, -5.09971799e-03f, - -5.10686735e-03f, -5.11337064e-03f, -5.11921194e-03f, -5.12430832e-03f, -5.12879029e-03f, -5.13247559e-03f, - -5.13558093e-03f, -5.13790406e-03f, -5.13959785e-03f, -5.14057003e-03f, -5.14087791e-03f, -5.14046226e-03f, - -5.13939285e-03f, -5.13762640e-03f, -5.13514185e-03f, -5.13200613e-03f, -5.12817221e-03f, -5.12364503e-03f, - -5.11845066e-03f, -5.11255113e-03f, -5.10600768e-03f, -5.09870948e-03f, -5.09082393e-03f, -5.08221619e-03f, - -5.07294411e-03f, -5.06298616e-03f, -5.05235768e-03f, -5.04106528e-03f, -5.02910057e-03f, -5.01647102e-03f, - -5.00319674e-03f, -4.98920703e-03f, -4.97461189e-03f, -4.95934935e-03f, -4.94342817e-03f, -4.92686121e-03f, - -4.90958630e-03f, -4.89177466e-03f, -4.87323552e-03f, -4.85412005e-03f, -4.83427514e-03f, -4.81388094e-03f, - -4.79282376e-03f, -4.77112487e-03f, -4.74882296e-03f, -4.72588165e-03f, -4.70234332e-03f, -4.67816480e-03f, - -4.65341973e-03f, -4.62806044e-03f, -4.60205405e-03f, -4.57548328e-03f, -4.54828251e-03f, -4.52057155e-03f, - -4.49217125e-03f, -4.46327926e-03f, -4.43372794e-03f, -4.40366529e-03f, -4.37301481e-03f, -4.34178269e-03f, - -4.30998078e-03f, -4.27770230e-03f, -4.24482293e-03f, -4.21134939e-03f, -4.17743042e-03f, -4.14286038e-03f, - -4.10783581e-03f, -4.07228304e-03f, -4.03619818e-03f, -3.99961692e-03f, -3.96245823e-03f, -3.92488671e-03f, - -3.88673261e-03f, -3.84814802e-03f, -3.80908460e-03f, -3.76945503e-03f, -3.72942781e-03f, -3.68885934e-03f, - -3.64787797e-03f, -3.60641947e-03f, -3.56451465e-03f, -3.52215271e-03f, -3.47936174e-03f, -3.43612626e-03f, - -3.39247322e-03f, -3.34835186e-03f, -3.30384293e-03f, -3.25893887e-03f, -3.21360231e-03f, -3.16787775e-03f, - -3.12175717e-03f, -3.07530130e-03f, -3.02836873e-03f, -2.98113592e-03f, -2.93350255e-03f, -2.88553368e-03f, - -2.83719752e-03f, -2.78853961e-03f, -2.73948397e-03f, -2.69015065e-03f, -2.64046498e-03f, -2.59050383e-03f, - -2.54019230e-03f, -2.48956430e-03f, -2.43864768e-03f, -2.38744249e-03f, -2.33598198e-03f, -2.28420404e-03f, - -2.23220653e-03f, -2.17990845e-03f, -2.12731191e-03f, -2.07454934e-03f, -2.02150831e-03f, -1.96827112e-03f, - -1.91476604e-03f, -1.86103469e-03f, -1.80709690e-03f, -1.75297266e-03f, -1.69867717e-03f, -1.64418204e-03f, - -1.58942894e-03f, -1.53456835e-03f, -1.47954860e-03f, -1.42437469e-03f, -1.36896029e-03f, -1.31354305e-03f, - -1.25787391e-03f, -1.20211448e-03f, -1.14623875e-03f, -1.09025190e-03f, -1.03416204e-03f, -9.77975343e-04f, - -9.21676517e-04f, -8.65275418e-04f, -8.08845557e-04f, -7.52301655e-04f, -6.95772282e-04f, -6.39116474e-04f, - -5.82462975e-04f, -5.25743222e-04f, -4.69009213e-04f, -4.12219026e-04f, -3.55443536e-04f, -2.98669115e-04f, - -2.41892432e-04f, -1.85073022e-04f, -1.28327706e-04f, -7.15706443e-05f, -1.48824555e-05f, 4.17697056e-05f, - 9.83906969e-05f, 1.54969664e-04f, 2.11517810e-04f, 2.67935299e-04f, 3.24284106e-04f, 3.80540693e-04f, - 4.36785836e-04f, 4.92869819e-04f, 5.48850403e-04f, 6.04705832e-04f, 6.60455087e-04f, 7.16081247e-04f, - 7.71606684e-04f, 8.26915033e-04f, 8.82093672e-04f, 9.37136017e-04f, 9.92022575e-04f, 1.04672267e-03f, - 1.10122905e-03f, 1.15555475e-03f, 1.20971129e-03f, 1.26364024e-03f, 1.31739932e-03f, 1.37085804e-03f, - 1.42418235e-03f, 1.47723683e-03f, 1.53008742e-03f, 1.58263898e-03f, 1.63497742e-03f, 1.68706549e-03f, - 1.73887230e-03f, 1.79045503e-03f, 1.84167986e-03f, 1.89268863e-03f, 1.94336194e-03f, 1.99378839e-03f, - 2.04385572e-03f, 2.09363481e-03f, 2.14311099e-03f, 2.19224430e-03f, 2.24107835e-03f, 2.28956906e-03f, - 2.33771290e-03f, 2.38550381e-03f, 2.43293395e-03f, 2.47997426e-03f, 2.52670126e-03f, 2.57304760e-03f, - 2.61904193e-03f, 2.66456387e-03f, 2.70976695e-03f, 2.75457165e-03f, 2.79897663e-03f, 2.84294096e-03f, - 2.88649102e-03f, 2.92967974e-03f, 2.97240179e-03f, 3.01467716e-03f, 3.05655598e-03f, 3.09797061e-03f, - 3.13894784e-03f, 3.17950909e-03f, 3.21953338e-03f, 3.25919828e-03f, 3.29833836e-03f, 3.33700808e-03f, - 3.37520750e-03f, 3.41293992e-03f, 3.45019750e-03f, 3.48692706e-03f, 3.52318523e-03f, 3.55893108e-03f, - 3.59418408e-03f, 3.62892995e-03f, 3.66319514e-03f, 3.69688415e-03f, 3.73014280e-03f, 3.76275302e-03f, - 3.79494385e-03f, 3.82657583e-03f, 3.85764841e-03f, 3.88817861e-03f, 3.91816779e-03f, 3.94764721e-03f, - 3.97651605e-03f, 4.00489501e-03f, 4.03267105e-03f, 4.05991461e-03f, 4.08657953e-03f, 4.11268014e-03f, - 4.13822396e-03f, 4.16315639e-03f, 4.18756660e-03f, 4.21134762e-03f, 4.23458254e-03f, 4.25724011e-03f, - 4.27924605e-03f, 4.30074087e-03f, 4.32158625e-03f, 4.34187041e-03f, 4.36158096e-03f, 4.38060794e-03f, - 4.39913482e-03f, 4.41696508e-03f, 4.43426094e-03f, 4.45093762e-03f, 4.46696490e-03f, 4.48243620e-03f, - 4.49725117e-03f, 4.51148845e-03f, 4.52508686e-03f, 4.53808465e-03f, 4.55047320e-03f, 4.56217464e-03f, - 4.57332981e-03f, 4.58386594e-03f, 4.59372358e-03f, 4.60302311e-03f, 4.61162311e-03f, 4.61969167e-03f, - 4.62705587e-03f, 4.63384909e-03f, 4.63998781e-03f, 4.64549108e-03f, 4.65036892e-03f, 4.65462297e-03f, - 4.65830091e-03f, 4.66132038e-03f, 4.66366807e-03f, 4.66541495e-03f, 4.66657949e-03f, 4.66706749e-03f, - 4.66697391e-03f, 4.66617619e-03f, 4.66481371e-03f, 4.66283704e-03f, 4.66020502e-03f, 4.65696635e-03f, - 4.65309888e-03f, 4.64863106e-03f, 4.64350105e-03f, 4.63782034e-03f, 4.63142792e-03f, 4.62451447e-03f, - 4.61692352e-03f, 4.60868711e-03f, 4.59996449e-03f, 4.59051088e-03f, 4.58052719e-03f, 4.56987705e-03f, - 4.55869640e-03f, 4.54684687e-03f, 4.53444072e-03f, 4.52136573e-03f, 4.50776761e-03f, 4.49351516e-03f, - 4.47876031e-03f, 4.46331472e-03f, 4.44733950e-03f, 4.43074970e-03f, 4.41360702e-03f, 4.39589542e-03f, - 4.37757988e-03f, 4.35870383e-03f, 4.33924993e-03f, 4.31924558e-03f, 4.29865993e-03f, 4.27747500e-03f, - 4.25576887e-03f, 4.23354029e-03f, 4.21072438e-03f, 4.18740765e-03f, 4.16342015e-03f, 4.13904593e-03f, - 4.11404332e-03f, 4.08853872e-03f, 4.06250248e-03f, 4.03592776e-03f, 4.00885136e-03f, 3.98125520e-03f, - 3.95312278e-03f, 3.92449627e-03f, 3.89536691e-03f, 3.86573621e-03f, 3.83559758e-03f, 3.80495853e-03f, - 3.77390200e-03f, 3.74226369e-03f, 3.71020310e-03f, 3.67766953e-03f, 3.64463973e-03f, 3.61118599e-03f, - 3.57722963e-03f, 3.54283995e-03f, 3.50796634e-03f, 3.47273488e-03f, 3.43699302e-03f, 3.40083448e-03f, - 3.36424191e-03f, 3.32722313e-03f, 3.28978165e-03f, 3.25191631e-03f, 3.21369300e-03f, 3.17501553e-03f, - 3.13595461e-03f, 3.09652388e-03f, 3.05668001e-03f, 3.01650248e-03f, 2.97588321e-03f, 2.93494833e-03f, - 2.89359432e-03f, 2.85193617e-03f, 2.80991015e-03f, 2.76751168e-03f, 2.72479969e-03f, 2.68176054e-03f, - 2.63839722e-03f, 2.59465933e-03f, 2.55066549e-03f, 2.50632488e-03f, 2.46172292e-03f, 2.41678866e-03f, - 2.37155925e-03f, 2.32607583e-03f, 2.28028347e-03f, 2.23420513e-03f, 2.18795161e-03f, 2.14132473e-03f, - 2.09449367e-03f, 2.04742713e-03f, 2.00012017e-03f, 1.95256409e-03f, 1.90477289e-03f, 1.85676798e-03f, - 1.80860892e-03f, 1.76018339e-03f, 1.71153530e-03f, 1.66273261e-03f, 1.61373161e-03f, 1.56454756e-03f, - 1.51518768e-03f, 1.46568864e-03f, 1.41597664e-03f, 1.36617992e-03f, 1.31616066e-03f, 1.26606924e-03f, - 1.21582301e-03f, 1.16542132e-03f, 1.11492843e-03f, 1.06434116e-03f, 1.01360701e-03f, 9.62796145e-04f, - 9.11873930e-04f, 8.60895616e-04f, 8.09802620e-04f, 7.58669219e-04f, 7.07506827e-04f, 6.56189171e-04f, - 6.04892928e-04f, 5.53570734e-04f, 5.02156596e-04f, 4.50744316e-04f, 3.99290220e-04f, 3.47816979e-04f, - 2.96342226e-04f, 2.44868442e-04f, 1.93426202e-04f, 1.41952079e-04f, 9.05547524e-05f, 3.91009050e-05f, - -1.22418288e-05f, -6.36059725e-05f, -1.14901825e-04f, -1.66140443e-04f, -2.17302444e-04f, -2.68426757e-04f, - -3.19465601e-04f, -3.70430364e-04f, -4.21300125e-04f, -4.72064437e-04f, -5.22761458e-04f, -5.73300083e-04f, - -6.23785348e-04f, -6.74102123e-04f, -7.24339153e-04f, -7.74376455e-04f, -8.24336599e-04f, -8.74106564e-04f, - -9.23756439e-04f, -9.73257918e-04f, -1.02249974e-03f, -1.07166469e-03f, -1.12059189e-03f, -1.16940039e-03f, - -1.21794153e-03f, -1.26633124e-03f, -1.31451898e-03f, -1.36246510e-03f, -1.41018397e-03f, -1.45770265e-03f, - -1.50500578e-03f, -1.55208737e-03f, -1.59884949e-03f, -1.64540769e-03f, -1.69173292e-03f, -1.73775682e-03f, - -1.78357707e-03f, -1.82903268e-03f, -1.87426925e-03f, -1.91919773e-03f, -1.96384752e-03f, -2.00823159e-03f, - -2.05227520e-03f, -2.09604844e-03f, -2.13944594e-03f, -2.18253488e-03f, -2.22535596e-03f, -2.26779798e-03f, - -2.30997693e-03f, -2.35173034e-03f, -2.39316347e-03f, -2.43426058e-03f, -2.47497089e-03f, -2.51534076e-03f, - -2.55538002e-03f, -2.59497724e-03f, -2.63423758e-03f, -2.67310141e-03f, -2.71159989e-03f, -2.74969029e-03f, - -2.78740721e-03f, -2.82469439e-03f, -2.86157125e-03f, -2.89803513e-03f, -2.93409693e-03f, -2.96979768e-03f, - -3.00497095e-03f, -3.03980295e-03f, -3.07408739e-03f, -3.10808933e-03f, -3.14150917e-03f, -3.17456957e-03f, - -3.20716768e-03f, -3.23926625e-03f, -3.27096685e-03f, -3.30218533e-03f, -3.33292026e-03f, -3.36317423e-03f, - -3.39302945e-03f, -3.42232289e-03f, -3.45116255e-03f, -3.47952977e-03f, -3.50741952e-03f, -3.53480911e-03f, - -3.56169764e-03f, -3.58807551e-03f, -3.61396166e-03f, -3.63940066e-03f, -3.66425778e-03f, -3.68865034e-03f, - -3.71251998e-03f, -3.73585690e-03f, -3.75867020e-03f, -3.78098213e-03f, -3.80278010e-03f, -3.82405188e-03f, - -3.84476870e-03f, -3.86499958e-03f, -3.88464256e-03f, -3.90380275e-03f, -3.92239410e-03f, -3.94044476e-03f, - -3.95795690e-03f, -3.97497172e-03f, -3.99137428e-03f, -4.00725004e-03f, -4.02258585e-03f, -4.03738250e-03f, - -4.05163445e-03f, -4.06527308e-03f, -4.07844448e-03f, -4.09098104e-03f, -4.10299009e-03f, -4.11442111e-03f, - -4.12534422e-03f, -4.13567389e-03f, -4.14546511e-03f, -4.15467572e-03f, -4.16331150e-03f, -4.17137973e-03f, - -4.17889243e-03f, -4.18586350e-03f, -4.19221687e-03f, -4.19806443e-03f, -4.20330431e-03f, -4.20799951e-03f, - -4.21213958e-03f, -4.21566517e-03f, -4.21864813e-03f, -4.22105383e-03f, -4.22289150e-03f, -4.22420210e-03f, - -4.22491681e-03f, -4.22508016e-03f, -4.22465163e-03f, -4.22367048e-03f, -4.22211152e-03f, -4.21998145e-03f, - -4.21733087e-03f, -4.21408310e-03f, -4.21029605e-03f, -4.20593282e-03f, -4.20099966e-03f, -4.19551331e-03f, - -4.18949160e-03f, -4.18289911e-03f, -4.17573181e-03f, -4.16803076e-03f, -4.15976963e-03f, -4.15096950e-03f, - -4.14162416e-03f, -4.13172142e-03f, -4.12123127e-03f, -4.11026345e-03f, -4.09870408e-03f, -4.08661800e-03f, - -4.07403055e-03f, -4.06088914e-03f, -4.04719350e-03f, -4.03294320e-03f, -4.01824545e-03f, -4.00289984e-03f, - -3.98714778e-03f, -3.97081248e-03f, -3.95397590e-03f, -3.93660682e-03f, -3.91872956e-03f, -3.90035988e-03f, - -3.88146367e-03f, -3.86202256e-03f, -3.84215239e-03f, -3.82176246e-03f, -3.80086800e-03f, -3.77942674e-03f, - -3.75759549e-03f, -3.73521477e-03f, -3.71234849e-03f, -3.68901819e-03f, -3.66518176e-03f, -3.64093562e-03f, - -3.61617949e-03f, -3.59092973e-03f, -3.56528299e-03f, -3.53914419e-03f, -3.51253357e-03f, -3.48549293e-03f, - -3.45799007e-03f, -3.43007906e-03f, -3.40168688e-03f, -3.37290281e-03f, -3.34363117e-03f, -3.31400261e-03f, - -3.28388398e-03f, -3.25343690e-03f, -3.22248846e-03f, -3.19115081e-03f, -3.15943387e-03f, -3.12732575e-03f, - -3.09479617e-03f, -3.06189223e-03f, -3.02856554e-03f, -2.99489017e-03f, -2.96084628e-03f, -2.92643647e-03f, - -2.89164065e-03f, -2.85649985e-03f, -2.82098470e-03f, -2.78511890e-03f, -2.74888146e-03f, -2.71238779e-03f, - -2.67545352e-03f, -2.63827076e-03f, -2.60071817e-03f, -2.56290264e-03f, -2.52468218e-03f, -2.48620737e-03f, - -2.44744707e-03f, -2.40832188e-03f, -2.36896711e-03f, -2.32927989e-03f, -2.28935711e-03f, -2.24908377e-03f, - -2.20863582e-03f, -2.16783432e-03f, -2.12685728e-03f, -2.08555797e-03f, -2.04404536e-03f, -2.00225657e-03f, - -1.96025481e-03f, -1.91804706e-03f, -1.87554061e-03f, -1.83288345e-03f, -1.78999116e-03f, -1.74688766e-03f, - -1.70360340e-03f, -1.66010400e-03f, -1.61639988e-03f, -1.57253190e-03f, -1.52850706e-03f, -1.48425133e-03f, - -1.43988882e-03f, -1.39530465e-03f, -1.35063764e-03f, -1.30578690e-03f, -1.26080735e-03f, -1.21567158e-03f, - -1.17041117e-03f, -1.12505491e-03f, -1.07956210e-03f, -1.03397311e-03f, -9.88257648e-04f, -9.42463289e-04f, - -8.96542800e-04f, -8.50577204e-04f, -8.04529387e-04f, -7.58381009e-04f, -7.12176542e-04f, -6.65879571e-04f, - -6.19627292e-04f, -5.73236310e-04f, -5.26859522e-04f, -4.80405400e-04f, -4.33921084e-04f, -3.87449460e-04f, - -3.40922749e-04f, -2.94408167e-04f, -2.47851528e-04f, -2.01382551e-04f, -1.54804591e-04f, -1.08355318e-04f, - -6.18613542e-05f, -1.54259328e-05f, 3.10211695e-05f, 7.73690751e-05f, 1.23763895e-04f, 1.70023742e-04f, - 2.16248403e-04f, 2.62395033e-04f, 3.08493414e-04f, 3.54531937e-04f, 4.00460824e-04f, 4.46309603e-04f, - 4.92015103e-04f, 5.37721859e-04f, 5.83264096e-04f, 6.28689517e-04f, 6.73993786e-04f, 7.19194579e-04f, - 7.64255690e-04f, 8.09198445e-04f, 8.53933754e-04f, 8.98621041e-04f, 9.43050536e-04f, 9.87405347e-04f, - 1.03152825e-03f, 1.07554742e-03f, 1.11932752e-03f, 1.16296839e-03f, 1.20639827e-03f, 1.24963185e-03f, - 1.29265499e-03f, 1.33551190e-03f, 1.37811736e-03f, 1.42054755e-03f, 1.46270026e-03f, 1.50469386e-03f, - 1.54638332e-03f, 1.58790101e-03f, 1.62912327e-03f, 1.67013274e-03f, 1.71084991e-03f, 1.75131399e-03f, - 1.79152762e-03f, 1.83148592e-03f, 1.87115289e-03f, 1.91054273e-03f, 1.94964691e-03f, 1.98843953e-03f, - 2.02695281e-03f, 2.06518107e-03f, 2.10307399e-03f, 2.14067370e-03f, 2.17795619e-03f, 2.21491936e-03f, - 2.25158503e-03f, 2.28787115e-03f, 2.32383137e-03f, 2.35950157e-03f, 2.39478353e-03f, 2.42973270e-03f, - 2.46432318e-03f, 2.49853510e-03f, 2.53246175e-03f, 2.56595051e-03f, 2.59908765e-03f, 2.63186841e-03f, - 2.66425411e-03f, 2.69627821e-03f, 2.72789116e-03f, 2.75914782e-03f, 2.79000673e-03f, 2.82046021e-03f, - 2.85051096e-03f, 2.88011579e-03f, 2.90937461e-03f, 2.93817710e-03f, 2.96662679e-03f, 2.99458741e-03f, - 3.02215552e-03f, 3.04932795e-03f, 3.07601865e-03f, 3.10229479e-03f, 3.12814149e-03f, 3.15355021e-03f, - 3.17853681e-03f, 3.20307121e-03f, 3.22711633e-03f, 3.25072285e-03f, 3.27391838e-03f, 3.29665872e-03f, - 3.31890823e-03f, 3.34067964e-03f, 3.36200811e-03f, 3.38290968e-03f, 3.40327442e-03f, 3.42320829e-03f, - 3.44266302e-03f, 3.46165337e-03f, 3.48012854e-03f, 3.49817587e-03f, 3.51568871e-03f, 3.53276665e-03f, - 3.54931937e-03f, 3.56539816e-03f, 3.58100329e-03f, 3.59608216e-03f, 3.61069942e-03f, 3.62480913e-03f, - 3.63843584e-03f, 3.65152151e-03f, 3.66416699e-03f, 3.67627568e-03f, 3.68791885e-03f, 3.69901681e-03f, - 3.70963099e-03f, 3.71974848e-03f, 3.72935136e-03f, 3.73843022e-03f, 3.74698416e-03f, 3.75512348e-03f, - 3.76268140e-03f, 3.76975265e-03f, 3.77626141e-03f, 3.78234916e-03f, 3.78788438e-03f, 3.79288320e-03f, - 3.79738910e-03f, 3.80139104e-03f, 3.80486380e-03f, 3.80784619e-03f, 3.81032425e-03f, 3.81223080e-03f, - 3.81370846e-03f, 3.81460079e-03f, 3.81501826e-03f, 3.81493409e-03f, 3.81432697e-03f, 3.81323375e-03f, - 3.81160840e-03f, 3.80943268e-03f, 3.80678733e-03f, 3.80362384e-03f, 3.79999057e-03f, 3.79585736e-03f, - 3.79114832e-03f, 3.78598220e-03f, 3.78030863e-03f, 3.77413182e-03f, 3.76744567e-03f, 3.76029043e-03f, - 3.75260292e-03f, 3.74442224e-03f, 3.73576693e-03f, 3.72660300e-03f, 3.71698662e-03f, 3.70682109e-03f, - 3.69618390e-03f, 3.68505679e-03f, 3.67343378e-03f, 3.66138634e-03f, 3.64884108e-03f, 3.63578704e-03f, - 3.62225658e-03f, 3.60825502e-03f, 3.59382116e-03f, 3.57884930e-03f, 3.56346997e-03f, 3.54756605e-03f, - 3.53127734e-03f, 3.51444026e-03f, 3.49723768e-03f, 3.47950427e-03f, 3.46136552e-03f, 3.44275900e-03f, - 3.42369216e-03f, 3.40420380e-03f, 3.38425800e-03f, 3.36389751e-03f, 3.34307955e-03f, 3.32183741e-03f, - 3.30019918e-03f, 3.27807778e-03f, 3.25558750e-03f, 3.23262622e-03f, 3.20929086e-03f, 3.18549085e-03f, - 3.16139106e-03f, 3.13678891e-03f, 3.11181697e-03f, 3.08645554e-03f, 3.06065857e-03f, 3.03452913e-03f, - 3.00800159e-03f, 2.98108412e-03f, 2.95375432e-03f, 2.92611076e-03f, 2.89800596e-03f, 2.86966262e-03f, - 2.84085810e-03f, 2.81170519e-03f, 2.78224626e-03f, 2.75243482e-03f, 2.72222264e-03f, 2.69168617e-03f, - 2.66087185e-03f, 2.62964185e-03f, 2.59814084e-03f, 2.56630029e-03f, 2.53413730e-03f, 2.50166583e-03f, - 2.46885981e-03f, 2.43578484e-03f, 2.40239282e-03f, 2.36872564e-03f, 2.33474403e-03f, 2.30044334e-03f, - 2.26593497e-03f, 2.23108404e-03f, 2.19599853e-03f, 2.16064811e-03f, 2.12502831e-03f, 2.08914069e-03f, - 2.05302722e-03f, 2.01663394e-03f, 1.98002952e-03f, 1.94315672e-03f, 1.90604615e-03f, 1.86876083e-03f, - 1.83120721e-03f, 1.79348652e-03f, 1.75551798e-03f, 1.71732957e-03f, 1.67896788e-03f, 1.64042057e-03f, - 1.60162682e-03f, 1.56272142e-03f, 1.52359245e-03f, 1.48433378e-03f, 1.44482220e-03f, 1.40526254e-03f, - 1.36543551e-03f, 1.32549785e-03f, 1.28544446e-03f, 1.24518238e-03f, 1.20486872e-03f, 1.16436266e-03f, - 1.12379008e-03f, 1.08304889e-03f, 1.04222353e-03f, 1.00123464e-03f, 9.60222696e-04f, 9.19048208e-04f, - 8.77810941e-04f, 8.36463011e-04f, 7.95083039e-04f, 7.53609648e-04f, 7.12072122e-04f, 6.70406909e-04f, - 6.28793516e-04f, 5.87032548e-04f, 5.45310128e-04f, 5.03463479e-04f, 4.61637448e-04f, 4.19769414e-04f, - 3.77871837e-04f, 3.35958675e-04f, 2.94014024e-04f, 2.52108078e-04f, 2.10139348e-04f, 1.68231361e-04f, - 1.26298030e-04f, 8.44253618e-05f, 4.25116598e-05f, 6.62360753e-07f, -4.11606362e-05f, -8.29504477e-05f, - -1.24673148e-04f, -1.66399235e-04f, -2.08022751e-04f, -2.49603539e-04f, -2.91101554e-04f, -3.32559296e-04f, - -3.73929542e-04f, -4.15192129e-04f, -4.56408218e-04f, -4.97539334e-04f, -5.38522996e-04f, -5.79406189e-04f, - -6.20199500e-04f, -6.60876085e-04f, -7.01417313e-04f, -7.41872729e-04f, -7.82152981e-04f, -8.22344300e-04f, - -8.62341513e-04f, -9.02252604e-04f, -9.41945027e-04f, -9.81560280e-04f, -1.02094150e-03f, -1.06019337e-03f, - -1.09920478e-03f, -1.13813986e-03f, -1.17683538e-03f, -1.21538212e-03f, -1.25366695e-03f, -1.29180710e-03f, - -1.32975348e-03f, -1.36742629e-03f, -1.40499236e-03f, -1.44226960e-03f, -1.47932890e-03f, -1.51618088e-03f, - -1.55275812e-03f, -1.58917887e-03f, -1.62526823e-03f, -1.66115689e-03f, -1.69678388e-03f, -1.73222689e-03f, - -1.76730975e-03f, -1.80218249e-03f, -1.83674770e-03f, -1.87107649e-03f, -1.90513278e-03f, -1.93890063e-03f, - -1.97233712e-03f, -2.00555640e-03f, -2.03840432e-03f, -2.07101089e-03f, -2.10332676e-03f, -2.13528538e-03f, - -2.16698388e-03f, -2.19833185e-03f, -2.22932918e-03f, -2.26007240e-03f, -2.29049894e-03f, -2.32052787e-03f, - -2.35024510e-03f, -2.37964525e-03f, -2.40870002e-03f, -2.43737226e-03f, -2.46575511e-03f, -2.49374267e-03f, - -2.52143775e-03f, -2.54866574e-03f, -2.57560820e-03f, -2.60215821e-03f, -2.62835687e-03f, -2.65418324e-03f, - -2.67961354e-03f, -2.70467680e-03f, -2.72939657e-03f, -2.75364741e-03f, -2.77758840e-03f, -2.80110024e-03f, - -2.82426845e-03f, -2.84696594e-03f, -2.86927764e-03f, -2.89123993e-03f, -2.91273308e-03f, -2.93389871e-03f, - -2.95457008e-03f, -2.97492650e-03f, -2.99480053e-03f, -3.01425538e-03f, -3.03329176e-03f, -3.05194363e-03f, - -3.07015521e-03f, -3.08793802e-03f, -3.10528597e-03f, -3.12225486e-03f, -3.13873380e-03f, -3.15477746e-03f, - -3.17040635e-03f, -3.18563931e-03f, -3.20035957e-03f, -3.21469073e-03f, -3.22853992e-03f, -3.24201096e-03f, - -3.25500685e-03f, -3.26753390e-03f, -3.27960107e-03f, -3.29128488e-03f, -3.30247727e-03f, -3.31322597e-03f, - -3.32350192e-03f, -3.33334795e-03f, -3.34276253e-03f, -3.35168177e-03f, -3.36019303e-03f, -3.36816823e-03f, - -3.37575422e-03f, -3.38286984e-03f, -3.38949011e-03f, -3.39571367e-03f, -3.40142693e-03f, -3.40673707e-03f, - -3.41153136e-03f, -3.41588922e-03f, -3.41979110e-03f, -3.42319424e-03f, -3.42620632e-03f, -3.42870484e-03f, - -3.43074890e-03f, -3.43232129e-03f, -3.43351563e-03f, -3.43413837e-03f, -3.43436784e-03f, -3.43407460e-03f, - -3.43340021e-03f, -3.43224212e-03f, -3.43063170e-03f, -3.42853050e-03f, -3.42596576e-03f, -3.42302333e-03f, - -3.41953269e-03f, -3.41563131e-03f, -3.41128335e-03f, -3.40647157e-03f, -3.40120185e-03f, -3.39548875e-03f, - -3.38932048e-03f, -3.38270948e-03f, -3.37565944e-03f, -3.36814408e-03f, -3.36019727e-03f, -3.35180133e-03f, - -3.34296894e-03f, -3.33368335e-03f, -3.32395230e-03f, -3.31386508e-03f, -3.30323121e-03f, -3.29223160e-03f, - -3.28073297e-03f, -3.26888501e-03f, -3.25658050e-03f, -3.24382495e-03f, -3.23068976e-03f, -3.21708814e-03f, - -3.20312650e-03f, -3.18867260e-03f, -3.17384617e-03f, -3.15857484e-03f, -3.14297356e-03f, -3.12686770e-03f, - -3.11042030e-03f, -3.09352386e-03f, -3.07627060e-03f, -3.05861075e-03f, -3.04052406e-03f, -3.02207177e-03f, - -3.00320933e-03f, -2.98400346e-03f, -2.96436504e-03f, -2.94435845e-03f, -2.92398802e-03f, -2.90323036e-03f, - -2.88212247e-03f, -2.86062535e-03f, -2.83875040e-03f, -2.81651985e-03f, -2.79394572e-03f, -2.77101604e-03f, - -2.74774389e-03f, -2.72411459e-03f, -2.70011444e-03f, -2.67575561e-03f, -2.65111675e-03f, -2.62610140e-03f, - -2.60078580e-03f, -2.57513546e-03f, -2.54913877e-03f, -2.52286505e-03f, -2.49620054e-03f, -2.46927852e-03f, - -2.44205773e-03f, -2.41447357e-03f, -2.38668251e-03f, -2.35849647e-03f, -2.33007950e-03f, -2.30130165e-03f, - -2.27232100e-03f, -2.24304018e-03f, -2.21351408e-03f, -2.18357077e-03f, -2.15350107e-03f, -2.12313766e-03f, - -2.09251121e-03f, -2.06159091e-03f, -2.03047486e-03f, -1.99906646e-03f, -1.96744055e-03f, -1.93558559e-03f, - -1.90344093e-03f, -1.87113446e-03f, -1.83857926e-03f, -1.80581628e-03f, -1.77280302e-03f, -1.73961404e-03f, - -1.70621675e-03f, -1.67256689e-03f, -1.63876547e-03f, -1.60477685e-03f, -1.57058019e-03f, -1.53620084e-03f, - -1.50167383e-03f, -1.46695926e-03f, -1.43203959e-03f, -1.39699232e-03f, -1.36176122e-03f, -1.32638846e-03f, - -1.29090169e-03f, -1.25522688e-03f, -1.21944673e-03f, -1.18348217e-03f, -1.14741420e-03f, -1.11121298e-03f, - -1.07492914e-03f, -1.03848025e-03f, -1.00194352e-03f, -9.65317641e-04f, -9.28572417e-04f, -8.91758265e-04f, - -8.54795745e-04f, -8.17784214e-04f, -7.80712663e-04f, -7.43516166e-04f, -7.06296274e-04f, -6.69008758e-04f, - -6.31650398e-04f, -5.94240418e-04f, -5.56753146e-04f, -5.19223195e-04f, -4.81686129e-04f, -4.44111620e-04f, - -4.06496612e-04f, -3.68887953e-04f, -3.31205903e-04f, -2.93523238e-04f, -2.55842450e-04f, -2.18174989e-04f, - -1.80431668e-04f, -1.42831786e-04f, -1.05110502e-04f, -6.74826369e-05f, -2.98503656e-05f, 7.72117209e-06f, - 4.53318383e-05f, 8.28934524e-05f, 1.20359380e-04f, 1.57834570e-04f, 1.95222405e-04f, 2.32567622e-04f, - 2.69842656e-04f, 3.07086705e-04f, 3.44200172e-04f, 3.81289415e-04f, 4.18282087e-04f, 4.55197775e-04f, - 4.92000111e-04f, 5.28723213e-04f, 5.65363403e-04f, 6.01845590e-04f, 6.38254244e-04f, 6.74552666e-04f, - 7.10748078e-04f, 7.46778898e-04f, 7.82725598e-04f, 8.18491095e-04f, 8.54147046e-04f, 8.89629093e-04f, - 9.25000844e-04f, 9.60225963e-04f, 9.95266231e-04f, 1.03014263e-03f, 1.06487871e-03f, 1.09946154e-03f, - 1.13380891e-03f, 1.16802993e-03f, 1.20200709e-03f, 1.23588749e-03f, 1.26947666e-03f, 1.30295990e-03f, - 1.33619051e-03f, 1.36923606e-03f, 1.40205168e-03f, 1.43467432e-03f, 1.46703874e-03f, 1.49921322e-03f, - 1.53119252e-03f, 1.56287211e-03f, 1.59437128e-03f, 1.62561917e-03f, 1.65662395e-03f, 1.68736653e-03f, - 1.71786834e-03f, 1.74815060e-03f, 1.77812834e-03f, 1.80786534e-03f, 1.83726748e-03f, 1.86652591e-03f, - 1.89545229e-03f, 1.92409837e-03f, 1.95245693e-03f, 1.98049786e-03f, 2.00836001e-03f, 2.03583477e-03f, - 2.06307329e-03f, 2.08995865e-03f, 2.11658045e-03f, 2.14290821e-03f, 2.16887847e-03f, 2.19457237e-03f, - 2.21995364e-03f, 2.24503096e-03f, 2.26974230e-03f, 2.29417298e-03f, 2.31825983e-03f, 2.34203109e-03f, - 2.36548418e-03f, 2.38851301e-03f, 2.41131226e-03f, 2.43372376e-03f, 2.45581072e-03f, 2.47751769e-03f, - 2.49889418e-03f, 2.51992139e-03f, 2.54059211e-03f, 2.56093699e-03f, 2.58088646e-03f, 2.60043453e-03f, - 2.61971622e-03f, 2.63857212e-03f, 2.65707030e-03f, 2.67520942e-03f, 2.69295967e-03f, 2.71036848e-03f, - 2.72734830e-03f, 2.74399511e-03f, 2.76023684e-03f, 2.77612302e-03f, 2.79160135e-03f, 2.80668663e-03f, - 2.82141089e-03f, 2.83573001e-03f, 2.84966667e-03f, 2.86316026e-03f, 2.87634509e-03f, 2.88908635e-03f, - 2.90149275e-03f, 2.91340195e-03f, 2.92498410e-03f, 2.93612320e-03f, 2.94685894e-03f, 2.95724014e-03f, - 2.96720834e-03f, 2.97673149e-03f, 2.98590035e-03f, 2.99460501e-03f, 3.00293120e-03f, 3.01085211e-03f, - 3.01836702e-03f, 3.02546556e-03f, 3.03215068e-03f, 3.03846507e-03f, 3.04430633e-03f, 3.04978508e-03f, - 3.05481303e-03f, 3.05947987e-03f, 3.06366336e-03f, 3.06747242e-03f, 3.07087916e-03f, 3.07385131e-03f, - 3.07644048e-03f, 3.07855353e-03f, 3.08034715e-03f, 3.08164094e-03f, 3.08257345e-03f, 3.08307150e-03f, - 3.08319619e-03f, 3.08282713e-03f, 3.08214312e-03f, 3.08098368e-03f, 3.07942958e-03f, 3.07740933e-03f, - 3.07507606e-03f, 3.07230759e-03f, 3.06909696e-03f, 3.06554915e-03f, 3.06148390e-03f, 3.05711693e-03f, - 3.05225345e-03f, 3.04706623e-03f, 3.04141989e-03f, 3.03539699e-03f, 3.02898701e-03f, 3.02215269e-03f, - 3.01493827e-03f, 3.00729213e-03f, 2.99930090e-03f, 2.99086140e-03f, 2.98209775e-03f, 2.97287669e-03f, - 2.96330305e-03f, 2.95334454e-03f, 2.94299842e-03f, 2.93220824e-03f, 2.92108352e-03f, 2.90958993e-03f, - 2.89769970e-03f, 2.88543806e-03f, 2.87278219e-03f, 2.85977305e-03f, 2.84638700e-03f, 2.83262706e-03f, - 2.81852850e-03f, 2.80401608e-03f, 2.78918407e-03f, 2.77394935e-03f, 2.75837106e-03f, 2.74246416e-03f, - 2.72617370e-03f, 2.70957537e-03f, 2.69257706e-03f, 2.67526137e-03f, 2.65755825e-03f, 2.63959295e-03f, - 2.62120555e-03f, 2.60251730e-03f, 2.58353373e-03f, 2.56415531e-03f, 2.54452722e-03f, 2.52449615e-03f, - 2.50416676e-03f, 2.48353660e-03f, 2.46262685e-03f, 2.44136849e-03f, 2.41975889e-03f, 2.39790583e-03f, - 2.37569141e-03f, 2.35326101e-03f, 2.33042882e-03f, 2.30738103e-03f, 2.28403866e-03f, 2.26040069e-03f, - 2.23648916e-03f, 2.21224953e-03f, 2.18776921e-03f, 2.16299169e-03f, 2.13801559e-03f, 2.11270003e-03f, - 2.08716719e-03f, 2.06132847e-03f, 2.03531155e-03f, 2.00896891e-03f, 1.98241783e-03f, 1.95559227e-03f, - 1.92860502e-03f, 1.90124504e-03f, 1.87379444e-03f, 1.84603257e-03f, 1.81809244e-03f, 1.78989471e-03f, - 1.76148866e-03f, 1.73287252e-03f, 1.70407610e-03f, 1.67503998e-03f, 1.64584814e-03f, 1.61636239e-03f, - 1.58679824e-03f, 1.55700617e-03f, 1.52699029e-03f, 1.49684563e-03f, 1.46648684e-03f, 1.43600957e-03f, - 1.40531278e-03f, 1.37449885e-03f, 1.34346184e-03f, 1.31230924e-03f, 1.28103848e-03f, 1.24959659e-03f, - 1.21798959e-03f, 1.18626597e-03f, 1.15441796e-03f, 1.12243176e-03f, 1.09032696e-03f, 1.05807619e-03f, - 1.02575652e-03f, 9.93270251e-04f, 9.60735966e-04f, 9.28046780e-04f, 8.95305078e-04f, 8.62450120e-04f, - 8.29476486e-04f, 7.96481870e-04f, 7.63376348e-04f, 7.30234529e-04f, 6.96916492e-04f, 6.63647015e-04f, - 6.30228914e-04f, 5.96822254e-04f, 5.63321778e-04f, 5.29818357e-04f, 4.96200155e-04f, 4.62617566e-04f, - 4.28927006e-04f, 3.95286330e-04f, 3.61546160e-04f, 3.27885097e-04f, 2.94073703e-04f, 2.60344792e-04f, - 2.26543186e-04f, 1.92794499e-04f, 1.59083016e-04f, 1.25282810e-04f, 9.15381186e-05f, 5.77841766e-05f, - 2.41201603e-05f, -9.59084363e-06f, -4.32073959e-05f, -7.68749413e-05f, -1.10430722e-04f, -1.43968648e-04f, - -1.77500039e-04f, -2.10916693e-04f, -2.44339172e-04f, -2.77653418e-04f, -3.10926323e-04f, -3.44106544e-04f, - -3.77222542e-04f, -4.10304128e-04f, -4.43237625e-04f, -4.76144941e-04f, -5.08897739e-04f, -5.41570770e-04f, - -5.74221095e-04f, -6.06690230e-04f, -6.39071837e-04f, -6.71359279e-04f, -7.03476246e-04f, -7.35531462e-04f, - -7.67435976e-04f, -7.99218981e-04f, -8.30872035e-04f, -8.62379243e-04f, -8.93732099e-04f, -9.24968512e-04f, - -9.56074232e-04f, -9.86964044e-04f, -1.01773549e-03f, -1.04834262e-03f, -1.07876712e-03f, -1.10903235e-03f, - -1.13912006e-03f, -1.16909474e-03f, -1.19880614e-03f, -1.22836635e-03f, -1.25770968e-03f, -1.28689843e-03f, - -1.31586745e-03f, -1.34464920e-03f, -1.37321761e-03f, -1.40160243e-03f, -1.42978918e-03f, -1.45770570e-03f, - -1.48541550e-03f, -1.51291799e-03f, -1.54019357e-03f, -1.56725638e-03f, -1.59409125e-03f, -1.62064890e-03f, - -1.64701542e-03f, -1.67310489e-03f, -1.69900029e-03f, -1.72460081e-03f, -1.74995318e-03f, -1.77504850e-03f, - -1.79990709e-03f, -1.82448991e-03f, -1.84882764e-03f, -1.87287372e-03f, -1.89666582e-03f, -1.92017095e-03f, - -1.94338687e-03f, -1.96638621e-03f, -1.98905439e-03f, -2.01145577e-03f, -2.03353280e-03f, -2.05538306e-03f, - -2.07687935e-03f, -2.09810736e-03f, -2.11904470e-03f, -2.13968807e-03f, -2.16002000e-03f, -2.18002542e-03f, - -2.19975620e-03f, -2.21916288e-03f, -2.23825040e-03f, -2.25701269e-03f, -2.27546654e-03f, -2.29362310e-03f, - -2.31147081e-03f, -2.32893224e-03f, -2.34613300e-03f, -2.36294137e-03f, -2.37948911e-03f, -2.39565274e-03f, - -2.41151422e-03f, -2.42702845e-03f, -2.44221717e-03f, -2.45703255e-03f, -2.47152465e-03f, -2.48572668e-03f, - -2.49951328e-03f, -2.51297985e-03f, -2.52612093e-03f, -2.53888678e-03f, -2.55127800e-03f, -2.56333834e-03f, - -2.57511330e-03f, -2.58647004e-03f, -2.59749065e-03f, -2.60815560e-03f, -2.61840457e-03f, -2.62838439e-03f, - -2.63794589e-03f, -2.64721738e-03f, -2.65602502e-03f, -2.66453037e-03f, -2.67267180e-03f, -2.68044472e-03f, - -2.68786772e-03f, -2.69488528e-03f, -2.70159083e-03f, -2.70789926e-03f, -2.71384321e-03f, -2.71940764e-03f, - -2.72460621e-03f, -2.72945617e-03f, -2.73391752e-03f, -2.73804938e-03f, -2.74176157e-03f, -2.74512859e-03f, - -2.74814108e-03f, -2.75076132e-03f, -2.75301610e-03f, -2.75490338e-03f, -2.75642606e-03f, -2.75757524e-03f, - -2.75835785e-03f, -2.75876957e-03f, -2.75878860e-03f, -2.75850020e-03f, -2.75779409e-03f, -2.75672725e-03f, - -2.75527646e-03f, -2.75348407e-03f, -2.75133679e-03f, -2.74881638e-03f, -2.74591800e-03f, -2.74269724e-03f, - -2.73904805e-03f, -2.73504463e-03f, -2.73072706e-03f, -2.72601511e-03f, -2.72093429e-03f, -2.71552086e-03f, - -2.70976510e-03f, -2.70357617e-03f, -2.69715137e-03f, -2.69023673e-03f, -2.68305349e-03f, -2.67548863e-03f, - -2.66759902e-03f, -2.65931235e-03f, -2.65073423e-03f, -2.64180531e-03f, -2.63247891e-03f, -2.62283408e-03f, - -2.61287631e-03f, -2.60252769e-03f, -2.59188062e-03f, -2.58087006e-03f, -2.56955356e-03f, -2.55787757e-03f, - -2.54587298e-03f, -2.53354014e-03f, -2.52087438e-03f, -2.50790926e-03f, -2.49460395e-03f, -2.48098683e-03f, - -2.46700937e-03f, -2.45275937e-03f, -2.43816533e-03f, -2.42330552e-03f, -2.40806073e-03f, -2.39254822e-03f, - -2.37672725e-03f, -2.36060327e-03f, -2.34416366e-03f, -2.32743970e-03f, -2.31046172e-03f, -2.29310420e-03f, - -2.27549823e-03f, -2.25757404e-03f, -2.23942294e-03f, -2.22093944e-03f, -2.20221127e-03f, -2.18316830e-03f, - -2.16383285e-03f, -2.14429525e-03f, -2.12442791e-03f, -2.10430861e-03f, -2.08395233e-03f, -2.06331721e-03f, - -2.04239584e-03f, -2.02125083e-03f, -1.99984710e-03f, -1.97820123e-03f, -1.95627884e-03f, -1.93416391e-03f, - -1.91177489e-03f, -1.88916323e-03f, -1.86628246e-03f, -1.84320967e-03f, -1.81991584e-03f, -1.79639669e-03f, - -1.77260283e-03f, -1.74867636e-03f, -1.72444243e-03f, -1.70007915e-03f, -1.67546123e-03f, -1.65071436e-03f, - -1.62567360e-03f, -1.60046219e-03f, -1.57507907e-03f, -1.54950742e-03f, -1.52377898e-03f, -1.49777043e-03f, - -1.47167146e-03f, -1.44538384e-03f, -1.41888797e-03f, -1.39224893e-03f, -1.36546706e-03f, -1.33850425e-03f, - -1.31137524e-03f, -1.28412967e-03f, -1.25665784e-03f, -1.22916148e-03f, -1.20143717e-03f, -1.17358911e-03f, - -1.14561432e-03f, -1.11748719e-03f, -1.08929419e-03f, -1.06095045e-03f, -1.03245505e-03f, -1.00387056e-03f, - -9.75186759e-04f, -9.46386768e-04f, -9.17501925e-04f, -8.88469947e-04f, -8.59393392e-04f, -8.30203545e-04f, - -8.00926401e-04f, -7.71604159e-04f, -7.42144595e-04f, -7.12657633e-04f, -6.83069290e-04f, -6.53454973e-04f, - -6.23731200e-04f, -5.93947011e-04f, -5.64128305e-04f, -5.34266136e-04f, -5.04369133e-04f, -4.74407736e-04f, - -4.44419252e-04f, -4.14380061e-04f, -3.84333625e-04f, -3.54238439e-04f, -3.24162153e-04f, -2.94000033e-04f, - -2.63883664e-04f, -2.33737251e-04f, -2.03585460e-04f, -1.73400037e-04f, -1.43246272e-04f, -1.13078496e-04f, - -8.29817870e-05f, -5.28762191e-05f, -2.27379493e-05f, 7.33911339e-06f, 3.73835381e-05f, 6.74057256e-05f, - 9.74039103e-05f, 1.27392166e-04f, 1.57256868e-04f, 1.87137443e-04f, 2.16940440e-04f, 2.46713045e-04f, - 2.76413359e-04f, 3.06075058e-04f, 3.35648082e-04f, 3.65120298e-04f, 3.94581060e-04f, 4.23915056e-04f, - 4.53225325e-04f, 4.82375225e-04f, 5.11473652e-04f, 5.40478888e-04f, 5.69417036e-04f, 5.98219669e-04f, - 6.26958035e-04f, 6.55506756e-04f, 6.84021645e-04f, 7.12374104e-04f, 7.40631793e-04f, 7.68753729e-04f, - 7.96765373e-04f, 8.24632147e-04f, 8.52381357e-04f, 8.79962557e-04f, 9.07418203e-04f, 9.34795376e-04f, - 9.61925232e-04f, 9.88964179e-04f, 1.01581631e-03f, 1.04251209e-03f, 1.06906318e-03f, 1.09541066e-03f, - 1.12167062e-03f, 1.14768710e-03f, 1.17359890e-03f, 1.19923864e-03f, 1.22473875e-03f, 1.25001532e-03f, - 1.27520271e-03f, 1.30015069e-03f, 1.32490555e-03f, 1.34944413e-03f, 1.37376956e-03f, 1.39790315e-03f, - 1.42186004e-03f, 1.44556394e-03f, 1.46908953e-03f, 1.49239454e-03f, 1.51548217e-03f, 1.53831044e-03f, - 1.56096828e-03f, 1.58332690e-03f, 1.60553771e-03f, 1.62753026e-03f, 1.64918838e-03f, 1.67065887e-03f, - 1.69185481e-03f, 1.71286127e-03f, 1.73360151e-03f, 1.75408760e-03f, 1.77433714e-03f, 1.79431650e-03f, - 1.81403758e-03f, 1.83348800e-03f, 1.85272052e-03f, 1.87166331e-03f, 1.89032532e-03f, 1.90876482e-03f, - 1.92685343e-03f, 1.94473230e-03f, 1.96235397e-03f, 1.97966914e-03f, 1.99669395e-03f, 2.01344030e-03f, - 2.02993787e-03f, 2.04610104e-03f, 2.06201710e-03f, 2.07765320e-03f, 2.09295202e-03f, 2.10799981e-03f, - 2.12269612e-03f, 2.13719765e-03f, 2.15128965e-03f, 2.16516495e-03f, 2.17868163e-03f, 2.19195594e-03f, - 2.20488159e-03f, 2.21749602e-03f, 2.22986015e-03f, 2.24186873e-03f, 2.25355990e-03f, 2.26496407e-03f, - 2.27606414e-03f, 2.28685823e-03f, 2.29729821e-03f, 2.30743566e-03f, 2.31727733e-03f, 2.32680238e-03f, - 2.33597332e-03f, 2.34485549e-03f, 2.35338385e-03f, 2.36163723e-03f, 2.36955361e-03f, 2.37712133e-03f, - 2.38441419e-03f, 2.39133597e-03f, 2.39798072e-03f, 2.40424192e-03f, 2.41023876e-03f, 2.41584083e-03f, - 2.42117807e-03f, 2.42611919e-03f, 2.43077708e-03f, 2.43512907e-03f, 2.43910735e-03f, 2.44281254e-03f, - 2.44614933e-03f, 2.44915318e-03f, 2.45184356e-03f, 2.45415669e-03f, 2.45621389e-03f, 2.45790572e-03f, - 2.45926116e-03f, 2.46031995e-03f, 2.46103710e-03f, 2.46138944e-03f, 2.46141823e-03f, 2.46115391e-03f, - 2.46057706e-03f, 2.45964926e-03f, 2.45835060e-03f, 2.45677507e-03f, 2.45485451e-03f, 2.45263314e-03f, - 2.45006430e-03f, 2.44718490e-03f, 2.44395687e-03f, 2.44042689e-03f, 2.43657433e-03f, 2.43236147e-03f, - 2.42788547e-03f, 2.42305020e-03f, 2.41793090e-03f, 2.41248349e-03f, 2.40668839e-03f, 2.40058677e-03f, - 2.39419069e-03f, 2.38747086e-03f, 2.38043304e-03f, 2.37311627e-03f, 2.36544294e-03f, 2.35751349e-03f, - 2.34917725e-03f, 2.34063167e-03f, 2.33173799e-03f, 2.32258457e-03f, 2.31307944e-03f, 2.30327267e-03f, - 2.29322184e-03f, 2.28283208e-03f, 2.27214481e-03f, 2.26118092e-03f, 2.24992509e-03f, 2.23837935e-03f, - 2.22649004e-03f, 2.21438085e-03f, 2.20194282e-03f, 2.18928898e-03f, 2.17628345e-03f, 2.16308215e-03f, - 2.14951340e-03f, 2.13566644e-03f, 2.12159388e-03f, 2.10724363e-03f, 2.09265516e-03f, 2.07774142e-03f, - 2.06262227e-03f, 2.04714936e-03f, 2.03151989e-03f, 2.01554351e-03f, 1.99938671e-03f, 1.98297780e-03f, - 1.96625953e-03f, 1.94932132e-03f, 1.93213988e-03f, 1.91469832e-03f, 1.89702869e-03f, 1.87912731e-03f, - 1.86098682e-03f, 1.84264240e-03f, 1.82403215e-03f, 1.80521735e-03f, 1.78613445e-03f, 1.76688458e-03f, - 1.74739310e-03f, 1.72764910e-03f, 1.70774399e-03f, 1.68757911e-03f, 1.66725355e-03f, 1.64671093e-03f, - 1.62595998e-03f, 1.60503229e-03f, 1.58388345e-03f, 1.56254191e-03f, 1.54098683e-03f, 1.51932641e-03f, - 1.49741017e-03f, 1.47532843e-03f, 1.45307644e-03f, 1.43063279e-03f, 1.40805106e-03f, 1.38525062e-03f, - 1.36235534e-03f, 1.33917109e-03f, 1.31599541e-03f, 1.29259648e-03f, 1.26901747e-03f, 1.24529174e-03f, - 1.22142002e-03f, 1.19742476e-03f, 1.17332812e-03f, 1.14900349e-03f, 1.12463029e-03f, 1.10007032e-03f, - 1.07541105e-03f, 1.05064092e-03f, 1.02575518e-03f, 1.00072876e-03f, 9.75570904e-04f, 9.50343581e-04f, - 9.25022652e-04f, 8.99545499e-04f, 8.74042480e-04f, 8.48373927e-04f, 8.22687263e-04f, 7.96816097e-04f, - 7.70961565e-04f, 7.44991221e-04f, 7.18901028e-04f, 6.92778613e-04f, 6.66597451e-04f, 6.40331778e-04f, - 6.13962741e-04f, 5.87612324e-04f, 5.61174940e-04f, 5.34672540e-04f, 5.08126644e-04f, 4.81530842e-04f, - 4.54921132e-04f, 4.28248178e-04f, 4.01537367e-04f, 3.74806914e-04f, 3.48057936e-04f, 3.21284428e-04f, - 2.94468359e-04f, 2.67661645e-04f, 2.40833058e-04f, 2.13984312e-04f, 1.87162842e-04f, 1.60278143e-04f, - 1.33468924e-04f, 1.06625843e-04f, 7.97818172e-05f, 5.29750145e-05f, 2.61678575e-05f, -6.02871043e-07f, - -2.73610288e-05f, -5.40890624e-05f, -8.07649183e-05f, -1.07458930e-04f, -1.34093581e-04f, -1.60681649e-04f, - -1.87231185e-04f, -2.13700580e-04f, -2.40158764e-04f, -2.66524115e-04f, -2.92909879e-04f, -3.19148296e-04f, - -3.45334825e-04f, -3.71462190e-04f, -3.97551582e-04f, -4.23547299e-04f, -4.49444438e-04f, -4.75276492e-04f, - -5.00995707e-04f, -5.26637780e-04f, -5.52235349e-04f, -5.77681475e-04f, -6.03025671e-04f, -6.28301223e-04f, - -6.53457973e-04f, -6.78491953e-04f, -7.03436341e-04f, -7.28263126e-04f, -7.52963299e-04f, -7.77541310e-04f, - -8.02000162e-04f, -8.26288735e-04f, -8.50480924e-04f, -8.74606086e-04f, -8.98490058e-04f, -9.22280867e-04f, - -9.45892515e-04f, -9.69408962e-04f, -9.92731734e-04f, -1.01592781e-03f, -1.03895878e-03f, -1.06183757e-03f, - -1.08457584e-03f, -1.10709117e-03f, -1.12948323e-03f, -1.15168265e-03f, -1.17374958e-03f, -1.19560325e-03f, - -1.21730448e-03f, -1.23882633e-03f, -1.26010498e-03f, -1.28124555e-03f, -1.30215732e-03f, -1.32297497e-03f, - -1.34349654e-03f, -1.36388091e-03f, -1.38402934e-03f, -1.40395746e-03f, -1.42374814e-03f, -1.44328096e-03f, - -1.46267667e-03f, -1.48178828e-03f, -1.50065107e-03f, -1.51938722e-03f, -1.53785862e-03f, -1.55614457e-03f, - -1.57415612e-03f, -1.59196272e-03f, -1.60952802e-03f, -1.62687114e-03f, -1.64399781e-03f, -1.66089811e-03f, - -1.67756353e-03f, -1.69396038e-03f, -1.71015766e-03f, -1.72607114e-03f, -1.74172105e-03f, -1.75717205e-03f, - -1.77240378e-03f, -1.78732603e-03f, -1.80200788e-03f, -1.81644802e-03f, -1.83064374e-03f, -1.84456561e-03f, - -1.85823521e-03f, -1.87162610e-03f, -1.88481704e-03f, -1.89768171e-03f, -1.91030311e-03f, -1.92265819e-03f, - -1.93476649e-03f, -1.94658084e-03f, -1.95813108e-03f, -1.96938527e-03f, -1.98041830e-03f, -1.99115495e-03f, - -2.00161196e-03f, -2.01178262e-03f, -2.02170714e-03f, -2.03133217e-03f, -2.04069025e-03f, -2.04976702e-03f, - -2.05856980e-03f, -2.06702613e-03f, -2.07525904e-03f, -2.08321392e-03f, -2.09090630e-03f, -2.09825460e-03f, - -2.10530862e-03f, -2.11211692e-03f, -2.11866744e-03f, -2.12486542e-03f, -2.13080020e-03f, -2.13643033e-03f, - -2.14182238e-03f, -2.14688609e-03f, -2.15163039e-03f, -2.15612693e-03f, -2.16033409e-03f, -2.16420541e-03f, - -2.16783002e-03f, -2.17117842e-03f, -2.17415831e-03f, -2.17691838e-03f, -2.17936550e-03f, -2.18152191e-03f, - -2.18335500e-03f, -2.18490593e-03f, -2.18620767e-03f, -2.18718006e-03f, -2.18786292e-03f, -2.18827060e-03f, - -2.18837371e-03f, -2.18818421e-03f, -2.18768625e-03f, -2.18692507e-03f, -2.18585068e-03f, -2.18451707e-03f, - -2.18284585e-03f, -2.18094831e-03f, -2.17873059e-03f, -2.17621863e-03f, -2.17343670e-03f, -2.17033654e-03f, - -2.16693645e-03f, -2.16330732e-03f, -2.15935572e-03f, -2.15515345e-03f, -2.15064776e-03f, -2.14586307e-03f, - -2.14080453e-03f, -2.13543099e-03f, -2.12978280e-03f, -2.12386400e-03f, -2.11768403e-03f, -2.11126583e-03f, - -2.10445742e-03f, -2.09747737e-03f, -2.09016760e-03f, -2.08266274e-03f, -2.07476832e-03f, -2.06670541e-03f, - -2.05832614e-03f, -2.04970216e-03f, -2.04078215e-03f, -2.03165258e-03f, -2.02215064e-03f, -2.01252755e-03f, - -2.00256286e-03f, -1.99237606e-03f, -1.98189818e-03f, -1.97114349e-03f, -1.96020795e-03f, -1.94897117e-03f, - -1.93755180e-03f, -1.92575010e-03f, -1.91383081e-03f, -1.90160198e-03f, -1.88920094e-03f, -1.87643298e-03f, - -1.86354291e-03f, -1.85038005e-03f, -1.83701634e-03f, -1.82331382e-03f, -1.80948378e-03f, -1.79531020e-03f, - -1.78107481e-03f, -1.76650589e-03f, -1.75171426e-03f, -1.73673812e-03f, -1.72154300e-03f, -1.70610501e-03f, - -1.69044723e-03f, -1.67460729e-03f, -1.65858145e-03f, -1.64231435e-03f, -1.62582629e-03f, -1.60916834e-03f, - -1.59227546e-03f, -1.57522414e-03f, -1.55794630e-03f, -1.54052708e-03f, -1.52285176e-03f, -1.50502750e-03f, - -1.48702959e-03f, -1.46878117e-03f, -1.45046236e-03f, -1.43186685e-03f, -1.41315336e-03f, -1.39427488e-03f, - -1.37514714e-03f, -1.35594050e-03f, -1.33655310e-03f, -1.31698169e-03f, -1.29723471e-03f, -1.27741167e-03f, - -1.25736314e-03f, -1.23718968e-03f, -1.21686445e-03f, -1.19640414e-03f, -1.17578381e-03f, -1.15503828e-03f, - -1.13414914e-03f, -1.11315150e-03f, -1.09200001e-03f, -1.07071825e-03f, -1.04933331e-03f, -1.02784397e-03f, - -1.00618215e-03f, -9.84430796e-04f, -9.62588047e-04f, -9.40574588e-04f, -9.18509967e-04f, -8.96388959e-04f, - -8.74070456e-04f, -8.51713840e-04f, -8.29225600e-04f, -8.06662445e-04f, -7.84042385e-04f, -7.61301168e-04f, - -7.38468928e-04f, -7.15611278e-04f, -6.92633530e-04f, -6.69594689e-04f, -6.46504261e-04f, -6.23317631e-04f, - -6.00079450e-04f, -5.76807927e-04f, -5.53447782e-04f, -5.30061166e-04f, -5.06621183e-04f, -4.83088936e-04f, - -4.59547124e-04f, -4.35935009e-04f, -4.12380855e-04f, -3.88684490e-04f, -3.65021528e-04f, -3.41287215e-04f, - -3.17590987e-04f, -2.93815903e-04f, -2.70045674e-04f, -2.46252618e-04f, -2.22428285e-04f, -1.98652354e-04f, - -1.74768633e-04f, -1.51037531e-04f, -1.27190669e-04f, -1.03391532e-04f, -7.95656522e-05f, -5.57779398e-05f, - -3.19821581e-05f, -8.23393738e-06f, 1.55011757e-05f, 3.92511571e-05f, 6.29218820e-05f, 8.66043176e-05f, - 1.10248093e-04f, 1.33807859e-04f, 1.57385887e-04f, 1.80879822e-04f, 2.04364468e-04f, 2.27779434e-04f, - 2.51170936e-04f, 2.74476834e-04f, 2.97745275e-04f, 3.20931096e-04f, 3.44060731e-04f, 3.67177750e-04f, - 3.90132371e-04f, 4.13092230e-04f, 4.35924159e-04f, 4.58708782e-04f, 4.81415445e-04f, 5.04004544e-04f, - 5.26494179e-04f, 5.48991618e-04f, 5.71274240e-04f, 5.93535188e-04f, 6.15696008e-04f, 6.37717203e-04f, - 6.59675000e-04f, 6.81490897e-04f, 7.03219763e-04f, 7.24823144e-04f, 7.46323766e-04f, 7.67685672e-04f, - 7.88927181e-04f, 8.10077909e-04f, 8.31089195e-04f, 8.51957815e-04f, 8.72675219e-04f, 8.93282065e-04f, - 9.13741777e-04f, 9.34086520e-04f, 9.54284478e-04f, 9.74330069e-04f, 9.94186497e-04f, 1.01395076e-03f, - 1.03350411e-03f, 1.05302612e-03f, 1.07224691e-03f, 1.09137620e-03f, 1.11031879e-03f, 1.12909885e-03f, - 1.14775367e-03f, 1.16617993e-03f, 1.18450200e-03f, 1.20256369e-03f, 1.22053509e-03f, 1.23829784e-03f, - 1.25584864e-03f, 1.27326846e-03f, 1.29042735e-03f, 1.30747424e-03f, 1.32429035e-03f, 1.34091784e-03f, - 1.35740419e-03f, 1.37363299e-03f, 1.38969620e-03f, 1.40554465e-03f, 1.42117898e-03f, 1.43665386e-03f, - 1.45187179e-03f, 1.46694559e-03f, 1.48174816e-03f, 1.49636704e-03f, 1.51076766e-03f, 1.52496385e-03f, - 1.53895030e-03f, 1.55269439e-03f, 1.56627291e-03f, 1.57956463e-03f, 1.59265969e-03f, 1.60553132e-03f, - 1.61816774e-03f, 1.63063402e-03f, 1.64278211e-03f, 1.65478304e-03f, 1.66648353e-03f, 1.67803096e-03f, - 1.68925732e-03f, 1.70029683e-03f, 1.71112058e-03f, 1.72163990e-03f, 1.73199683e-03f, 1.74204953e-03f, - 1.75189759e-03f, 1.76151893e-03f, 1.77084776e-03f, 1.77995595e-03f, 1.78879641e-03f, 1.79745738e-03f, - 1.80587187e-03f, 1.81398196e-03f, 1.82182835e-03f, 1.82946308e-03f, 1.83683022e-03f, 1.84397053e-03f, - 1.85081889e-03f, 1.85746954e-03f, 1.86383175e-03f, 1.86994568e-03f, 1.87580119e-03f, 1.88142450e-03f, - 1.88674762e-03f, 1.89188751e-03f, 1.89670286e-03f, 1.90127923e-03f, 1.90563576e-03f, 1.90967424e-03f, - 1.91350426e-03f, 1.91701946e-03f, 1.92034263e-03f, 1.92337809e-03f, 1.92614724e-03f, 1.92867815e-03f, - 1.93094722e-03f, 1.93293315e-03f, 1.93468408e-03f, 1.93615214e-03f, 1.93737664e-03f, 1.93833627e-03f, - 1.93905415e-03f, 1.93950841e-03f, 1.93971661e-03f, 1.93963338e-03f, 1.93930131e-03f, 1.93872910e-03f, - 1.93787845e-03f, 1.93675641e-03f, 1.93543093e-03f, 1.93381445e-03f, 1.93195361e-03f, 1.92983778e-03f, - 1.92742406e-03f, 1.92482500e-03f, 1.92194071e-03f, 1.91877441e-03f, 1.91540368e-03f, 1.91177436e-03f, - 1.90789579e-03f, 1.90372588e-03f, 1.89933696e-03f, 1.89468313e-03f, 1.88978829e-03f, 1.88463979e-03f, - 1.87929555e-03f, 1.87371017e-03f, 1.86779752e-03f, 1.86164985e-03f, 1.85529971e-03f, 1.84875328e-03f, - 1.84188408e-03f, 1.83482091e-03f, 1.82747480e-03f, 1.81993662e-03f, 1.81217840e-03f, 1.80413365e-03f, - 1.79588470e-03f, 1.78742947e-03f, 1.77867654e-03f, 1.76975612e-03f, 1.76057014e-03f, 1.75116021e-03f, - 1.74156050e-03f, 1.73173494e-03f, 1.72167019e-03f, 1.71137806e-03f, 1.70087927e-03f, 1.69016298e-03f, - 1.67920037e-03f, 1.66805594e-03f, 1.65674120e-03f, 1.64513942e-03f, 1.63336527e-03f, 1.62137525e-03f, - 1.60919534e-03f, 1.59683804e-03f, 1.58421227e-03f, 1.57142606e-03f, 1.55842626e-03f, 1.54525581e-03f, - 1.53185584e-03f, 1.51829553e-03f, 1.50455849e-03f, 1.49060353e-03f, 1.47646046e-03f, 1.46212920e-03f, - 1.44763949e-03f, 1.43297738e-03f, 1.41812139e-03f, 1.40308822e-03f, 1.38789341e-03f, 1.37250535e-03f, - 1.35699580e-03f, 1.34126425e-03f, 1.32538198e-03f, 1.30935383e-03f, 1.29316787e-03f, 1.27682291e-03f, - 1.26032006e-03f, 1.24366147e-03f, 1.22684362e-03f, 1.20990266e-03f, 1.19278480e-03f, 1.17553543e-03f, - 1.15817752e-03f, 1.14063807e-03f, 1.12299196e-03f, 1.10518971e-03f, 1.08725154e-03f, 1.06922511e-03f, - 1.05105726e-03f, 1.03274506e-03f, 1.01431101e-03f, 9.95794426e-04f, 9.77133005e-04f, 9.58354614e-04f, - 9.39443205e-04f, 9.20521831e-04f, 9.01376275e-04f, 8.82242629e-04f, 8.62903499e-04f, 8.43559807e-04f, - 8.24056749e-04f, 8.04455467e-04f, 7.84839628e-04f, 7.65066848e-04f, 7.45207920e-04f, 7.25287350e-04f, - 7.05298687e-04f, 6.85245369e-04f, 6.65077702e-04f, 6.44895799e-04f, 6.24626816e-04f, 6.04259089e-04f, - 5.83872118e-04f, 5.63381752e-04f, 5.42853691e-04f, 5.22297811e-04f, 5.01667196e-04f, 4.81003997e-04f, - 4.60242434e-04f, 4.39504245e-04f, 4.18729285e-04f, 3.97859177e-04f, 3.77025633e-04f, 3.56079914e-04f, - 3.35189794e-04f, 3.14202255e-04f, 2.93237401e-04f, 2.72224851e-04f, 2.51252501e-04f, 2.30192720e-04f, - 2.09154576e-04f, 1.88090902e-04f, 1.67052087e-04f, 1.45998117e-04f, 1.24948244e-04f, 1.03870029e-04f, - 8.28125459e-05f, 6.17646063e-05f, 4.07830594e-05f, 1.97154057e-05f, -1.26003513e-06f, -2.22408002e-05f, - -4.31866105e-05f, -6.41208415e-05f, -8.50380191e-05f, -1.05913174e-04f, -1.26756492e-04f, -1.47575797e-04f, - -1.68347842e-04f, -1.89053233e-04f, -2.09743099e-04f, -2.30378671e-04f, -2.50966172e-04f, -2.71492030e-04f, - -2.91971108e-04f, -3.12384554e-04f, -3.32766898e-04f, -3.53046483e-04f, -3.73287336e-04f, -3.93463664e-04f, - -4.13576363e-04f, -4.33560796e-04f, -4.53520104e-04f, -4.73350984e-04f, -4.93160031e-04f, -5.12898858e-04f, - -5.32477539e-04f, -5.51964510e-04f, -5.71448144e-04f, -5.90762386e-04f, -6.10051498e-04f, -6.29170777e-04f, - -6.48211496e-04f, -6.67170542e-04f, -6.85981585e-04f, -7.04737328e-04f, -7.23300593e-04f, -7.41864362e-04f, - -7.60235584e-04f, -7.78457894e-04f, -7.96638021e-04f, -8.14660276e-04f, -8.32579096e-04f, -8.50352729e-04f, - -8.67993381e-04f, -8.85490348e-04f, -9.02869906e-04f, -9.20131138e-04f, -9.37230728e-04f, -9.54187689e-04f, - -9.70996934e-04f, -9.87699968e-04f, -1.00423987e-03f, -1.02063228e-03f, -1.03683380e-03f, -1.05291323e-03f, - -1.06883687e-03f, -1.08462580e-03f, -1.10022704e-03f, -1.11569158e-03f, -1.13093987e-03f, -1.14607921e-03f, - -1.16102326e-03f, -1.17581866e-03f, -1.19043849e-03f, -1.20488971e-03f, -1.21915269e-03f, -1.23327188e-03f, - -1.24717998e-03f, -1.26094040e-03f, -1.27447559e-03f, -1.28786832e-03f, -1.30105154e-03f, -1.31409735e-03f, - -1.32688706e-03f, -1.33953185e-03f, -1.35199116e-03f, -1.36420863e-03f, -1.37630589e-03f, -1.38815713e-03f, - -1.39983589e-03f, -1.41131696e-03f, -1.42261775e-03f, -1.43368347e-03f, -1.44455882e-03f, -1.45524987e-03f, - -1.46570260e-03f, -1.47598108e-03f, -1.48602797e-03f, -1.49588846e-03f, -1.50555171e-03f, -1.51500594e-03f, - -1.52422857e-03f, -1.53323911e-03f, -1.54203938e-03f, -1.55062626e-03f, -1.55904250e-03f, -1.56716591e-03f, - -1.57514242e-03f, -1.58286500e-03f, -1.59039209e-03f, -1.59771819e-03f, -1.60475809e-03f, -1.61157098e-03f, - -1.61826353e-03f, -1.62469071e-03f, -1.63086864e-03f, -1.63684920e-03f, -1.64256107e-03f, -1.64811816e-03f, - -1.65344666e-03f, -1.65849587e-03f, -1.66336715e-03f, -1.66797600e-03f, -1.67235989e-03f, -1.67655300e-03f, - -1.68048709e-03f, -1.68423956e-03f, -1.68770168e-03f, -1.69100317e-03f, -1.69399693e-03f, -1.69688468e-03f, - -1.69939318e-03f, -1.70176670e-03f, -1.70389426e-03f, -1.70576671e-03f, -1.70750931e-03f, -1.70890424e-03f, - -1.71013831e-03f, -1.71109938e-03f, -1.71186155e-03f, -1.71236327e-03f, -1.71268590e-03f, -1.71277147e-03f, - -1.71262502e-03f, -1.71224005e-03f, -1.71158564e-03f, -1.71079428e-03f, -1.70972909e-03f, -1.70844750e-03f, - -1.70691430e-03f, -1.70515719e-03f, -1.70321632e-03f, -1.70101888e-03f, -1.69860905e-03f, -1.69598152e-03f, - -1.69311817e-03f, -1.69001379e-03f, -1.68672817e-03f, -1.68320317e-03f, -1.67945775e-03f, -1.67552840e-03f, - -1.67128791e-03f, -1.66694331e-03f, -1.66231580e-03f, -1.65743647e-03f, -1.65240749e-03f, -1.64715856e-03f, - -1.64168816e-03f, -1.63595970e-03f, -1.63007051e-03f, -1.62394063e-03f, -1.61763483e-03f, -1.61109699e-03f, - -1.60434630e-03f, -1.59740726e-03f, -1.59026189e-03f, -1.58286653e-03f, -1.57534259e-03f, -1.56758503e-03f, - -1.55959620e-03f, -1.55143073e-03f, -1.54305115e-03f, -1.53452379e-03f, -1.52576948e-03f, -1.51682278e-03f, - -1.50763463e-03f, -1.49831598e-03f, -1.48875919e-03f, -1.47909672e-03f, -1.46918252e-03f, -1.45906616e-03f, - -1.44882858e-03f, -1.43834138e-03f, -1.42772309e-03f, -1.41690346e-03f, -1.40591601e-03f, -1.39473645e-03f, - -1.38339327e-03f, -1.37188021e-03f, -1.36014905e-03f, -1.34833609e-03f, -1.33630763e-03f, -1.32407545e-03f, - -1.31172802e-03f, -1.29920765e-03f, -1.28652029e-03f, -1.27369320e-03f, -1.26067561e-03f, -1.24754816e-03f, - -1.23424213e-03f, -1.22076639e-03f, -1.20717866e-03f, -1.19336286e-03f, -1.17952575e-03f, -1.16541553e-03f, - -1.15128695e-03f, -1.13690998e-03f, -1.12249634e-03f, -1.10787347e-03f, -1.09315805e-03f, -1.07829547e-03f, - -1.06325967e-03f, -1.04813916e-03f, -1.03292668e-03f, -1.01755636e-03f, -1.00207106e-03f, -9.86433297e-04f, - -9.70688503e-04f, -9.54880970e-04f, -9.38924105e-04f, -9.22869362e-04f, -9.06704499e-04f, -8.90417962e-04f, - -8.74046494e-04f, -8.57598742e-04f, -8.40992924e-04f, -8.24308853e-04f, -8.07556496e-04f, -7.90651247e-04f, - -7.73755601e-04f, -7.56707610e-04f, -7.39599745e-04f, -7.22391325e-04f, -7.05075440e-04f, -6.87761519e-04f, - -6.70337968e-04f, -6.52825128e-04f, -6.35252594e-04f, -6.17574922e-04f, -5.99892510e-04f, -5.82096208e-04f, - -5.64278025e-04f, -5.46361791e-04f, -5.28433526e-04f, -5.10443431e-04f, -4.92382789e-04f, -4.74279069e-04f, - -4.56129034e-04f, -4.37959470e-04f, -4.19730135e-04f, -4.01438989e-04f, -3.83144678e-04f, -3.64793572e-04f, - -3.46403153e-04f, -3.28052218e-04f, -3.09615654e-04f, -2.91156866e-04f, -2.72654409e-04f, -2.54191565e-04f, - -2.35683578e-04f, -2.17205674e-04f, -1.98592352e-04f, -1.80086531e-04f, -1.61547088e-04f, -1.42987716e-04f, - -1.24433284e-04f, -1.05890418e-04f, -8.73664846e-05f, -6.88180087e-05f, -5.02512815e-05f, -3.17140315e-05f, - -1.32312656e-05f, 5.27562221e-06f, 2.37303996e-05f, 4.22094232e-05f, 6.06326032e-05f, 7.90428239e-05f, - 9.74217671e-05f, 1.15800582e-04f, 1.34100659e-04f, 1.52378960e-04f, 1.70635339e-04f, 1.88823931e-04f, - 2.07013986e-04f, 2.25088078e-04f, 2.43170461e-04f, 2.61215016e-04f, 2.79170695e-04f, 2.97108072e-04f, - 3.14944445e-04f, 3.32769637e-04f, 3.50516462e-04f, 3.68217583e-04f, 3.85761371e-04f, 4.03329800e-04f, - 4.20826133e-04f, 4.38223085e-04f, 4.55567393e-04f, 4.72805242e-04f, 4.89986237e-04f, 5.07056920e-04f, - 5.24078797e-04f, 5.40982188e-04f, 5.57814828e-04f, 5.74601172e-04f, 5.91241210e-04f, 6.07776945e-04f, - 6.24276150e-04f, 6.40617157e-04f, 6.56897391e-04f, 6.73054667e-04f, 6.89103031e-04f, 7.05064921e-04f, - 7.20858743e-04f, 7.36667973e-04f, 7.52245163e-04f, 7.67774024e-04f, 7.83129429e-04f, 7.98428085e-04f, - 8.13532456e-04f, 8.28587980e-04f, 8.43504049e-04f, 8.58269662e-04f, 8.72923656e-04f, 8.87465493e-04f, - 9.01818546e-04f, 9.16068325e-04f, 9.30209817e-04f, 9.44202866e-04f, 9.58044173e-04f, 9.71754472e-04f, - 9.85287447e-04f, 9.98690066e-04f, 1.01199981e-03f, 1.02512796e-03f, 1.03809355e-03f, 1.05093324e-03f, - 1.06361076e-03f, 1.07614594e-03f, 1.08849565e-03f, 1.10072378e-03f, 1.11277158e-03f, 1.12469668e-03f, - 1.13639872e-03f, 1.14799665e-03f, 1.15940346e-03f, 1.17064044e-03f, 1.18170979e-03f, 1.19266113e-03f, - 1.20338092e-03f, 1.21395227e-03f, 1.22437129e-03f, 1.23459801e-03f, 1.24464419e-03f, 1.25453671e-03f, - 1.26427697e-03f, 1.27379349e-03f, 1.28314942e-03f, 1.29229772e-03f, 1.30132873e-03f, 1.31010884e-03f, - 1.31876613e-03f, 1.32717053e-03f, 1.33551512e-03f, 1.34352067e-03f, 1.35145898e-03f, 1.35915640e-03f, - 1.36667333e-03f, 1.37401630e-03f, 1.38115160e-03f, 1.38808697e-03f, 1.39484541e-03f, 1.40144192e-03f, - 1.40779018e-03f, 1.41399626e-03f, 1.41999279e-03f, 1.42578333e-03f, 1.43141352e-03f, 1.43677296e-03f, - 1.44201655e-03f, 1.44703002e-03f, 1.45185454e-03f, 1.45648150e-03f, 1.46088925e-03f, 1.46507875e-03f, - 1.46917045e-03f, 1.47295944e-03f, 1.47663425e-03f, 1.48004204e-03f, 1.48325689e-03f, 1.48629178e-03f, - 1.48914963e-03f, 1.49182049e-03f, 1.49420431e-03f, 1.49642693e-03f, 1.49845264e-03f, 1.50032609e-03f, - 1.50194578e-03f, 1.50336241e-03f, 1.50458519e-03f, 1.50558931e-03f, 1.50646571e-03f, 1.50704035e-03f, - 1.50748837e-03f, 1.50772848e-03f, 1.50775597e-03f, 1.50760558e-03f, 1.50715639e-03f, 1.50667091e-03f, - 1.50583754e-03f, 1.50493951e-03f, 1.50368168e-03f, 1.50236601e-03f, 1.50076921e-03f, 1.49900483e-03f, - 1.49706652e-03f, 1.49487330e-03f, 1.49255776e-03f, 1.48999768e-03f, 1.48726334e-03f, 1.48431807e-03f, - 1.48116274e-03f, 1.47784614e-03f, 1.47434224e-03f, 1.47064580e-03f, 1.46673969e-03f, 1.46262807e-03f, - 1.45833604e-03f, 1.45387234e-03f, 1.44919224e-03f, 1.44434572e-03f, 1.43932098e-03f, 1.43413129e-03f, - 1.42870410e-03f, 1.42311128e-03f, 1.41735114e-03f, 1.41138086e-03f, 1.40525130e-03f, 1.39889481e-03f, - 1.39245930e-03f, 1.38570648e-03f, 1.37888801e-03f, 1.37184751e-03f, 1.36467588e-03f, 1.35727428e-03f, - 1.34974847e-03f, 1.34200422e-03f, 1.33411193e-03f, 1.32604899e-03f, 1.31783309e-03f, 1.30941450e-03f, - 1.30084349e-03f, 1.29212753e-03f, 1.28321466e-03f, 1.27417601e-03f, 1.26496994e-03f, 1.25561942e-03f, - 1.24608680e-03f, 1.23640358e-03f, 1.22654787e-03f, 1.21653712e-03f, 1.20641207e-03f, 1.19610943e-03f, - 1.18569604e-03f, 1.17507574e-03f, 1.16437232e-03f, 1.15344414e-03f, 1.14242448e-03f, 1.13126616e-03f, - 1.11997632e-03f, 1.10853563e-03f, 1.09696885e-03f, 1.08527176e-03f, 1.07340574e-03f, 1.06145135e-03f, - 1.04930787e-03f, 1.03708842e-03f, 1.02472110e-03f, 1.01226494e-03f, 9.99641440e-04f, 9.86952535e-04f, - 9.74088141e-04f, 9.61163129e-04f, 9.48042387e-04f, 9.34892406e-04f, 9.21568440e-04f, 9.08157665e-04f, - 8.94650757e-04f, 8.80988866e-04f, 8.67311073e-04f, 8.53483705e-04f, 8.39576007e-04f, 8.25553303e-04f, - 8.11415602e-04f, 7.97217063e-04f, 7.82867025e-04f, 7.68509972e-04f, 7.54037139e-04f, 7.39437481e-04f, - 7.24795555e-04f, 7.10033989e-04f, 6.95247947e-04f, 6.80352706e-04f, 6.65390454e-04f, 6.50331026e-04f, - 6.35221067e-04f, 6.20038474e-04f, 6.04771331e-04f, 5.89475370e-04f, 5.74104571e-04f, 5.58647023e-04f, - 5.43167930e-04f, 5.27584058e-04f, 5.11982542e-04f, 4.96317738e-04f, 4.80579289e-04f, 4.64820079e-04f, - 4.49005753e-04f, 4.33153787e-04f, 4.17245164e-04f, 4.01353037e-04f, 3.85350171e-04f, 3.69331757e-04f, - 3.53322230e-04f, 3.37196136e-04f, 3.21124688e-04f, 3.04991861e-04f, 2.88820385e-04f, 2.72642416e-04f, - 2.56426984e-04f, 2.40222784e-04f, 2.23992924e-04f, 2.07734022e-04f, 1.91464888e-04f, 1.75225078e-04f, - 1.58936150e-04f, 1.42639394e-04f, 1.26330146e-04f, 1.10084949e-04f, 9.37930008e-05f, 7.75517056e-05f, - 6.11870685e-05f, 4.49656183e-05f, 2.86564149e-05f, 1.24575852e-05f, -3.77880727e-06f, -2.00100162e-05f, - -3.62046072e-05f, -5.23977263e-05f, -6.85335468e-05f, -8.46765663e-05f, -1.00772089e-04f, -1.16883420e-04f, - -1.32910636e-04f, -1.48927434e-04f, -1.64889457e-04f, -1.80809666e-04f, -1.96747361e-04f, -2.12585046e-04f, - -2.28426606e-04f, -2.44181403e-04f, -2.59906378e-04f, -2.75587353e-04f, -2.91224476e-04f, -3.06774421e-04f, - -3.22257626e-04f, -3.37715974e-04f, -3.53112924e-04f, -3.68472924e-04f, -3.83736566e-04f, -3.98959506e-04f, - -4.14058261e-04f, -4.29101044e-04f, -4.44162270e-04f, -4.59055398e-04f, -4.73915199e-04f, -4.88654431e-04f, - -5.03348611e-04f, -5.17976344e-04f, -5.32518804e-04f, -5.46932324e-04f, -5.61265101e-04f, -5.75544357e-04f, - -5.89773273e-04f, -6.03817262e-04f, -6.17842999e-04f, -6.31725581e-04f, -6.45502261e-04f, -6.59206450e-04f, - -6.72821542e-04f, -6.86292148e-04f, -6.99688354e-04f, -7.12986667e-04f, -7.26174746e-04f, -7.39249827e-04f, - -7.52229783e-04f, -7.65032055e-04f, -7.77801318e-04f, -7.90403996e-04f, -8.02907157e-04f, -8.15305239e-04f, - -8.27553828e-04f, -8.39719900e-04f, -8.51700935e-04f, -8.63626606e-04f, -8.75382488e-04f, -8.87032032e-04f, - -8.98545747e-04f, -9.09928881e-04f, -9.21184818e-04f, -9.32296949e-04f, -9.43273834e-04f, -9.54132567e-04f, - -9.64784500e-04f, -9.75436059e-04f, -9.85843133e-04f, -9.96156855e-04f, -1.00631693e-03f, -1.01629212e-03f, - -1.02619362e-03f, -1.03585871e-03f, -1.04547827e-03f, -1.05484706e-03f, -1.06418324e-03f, -1.07329425e-03f, - -1.08221817e-03f, -1.09108600e-03f, -1.09973590e-03f, -1.10829701e-03f, -1.11662212e-03f, -1.12483022e-03f, - -1.13285858e-03f, -1.14076681e-03f, -1.14850102e-03f, -1.15605554e-03f, -1.16348754e-03f, -1.17074439e-03f, - -1.17778681e-03f, -1.18474101e-03f, -1.19150874e-03f, -1.19809638e-03f, -1.20449290e-03f, -1.21082746e-03f, - -1.21690746e-03f, -1.22283848e-03f, -1.22859004e-03f, -1.23417973e-03f, -1.23963031e-03f, -1.24487384e-03f, - -1.24992104e-03f, -1.25490116e-03f, -1.25961811e-03f, -1.26418835e-03f, -1.26862237e-03f, -1.27281313e-03f, - -1.27691575e-03f, -1.28074608e-03f, -1.28451211e-03f, -1.28803811e-03f, -1.29140065e-03f, -1.29457319e-03f, - -1.29758886e-03f, -1.30045718e-03f, -1.30309587e-03f, -1.30558726e-03f, -1.30791356e-03f, -1.31003743e-03f, - -1.31203789e-03f, -1.31380231e-03f, -1.31541965e-03f, -1.31686385e-03f, -1.31813745e-03f, -1.31918074e-03f, - -1.32011396e-03f, -1.32084958e-03f, -1.32139624e-03f, -1.32178122e-03f, -1.32197726e-03f, -1.32205454e-03f, - -1.32187653e-03f, -1.32159345e-03f, -1.32107507e-03f, -1.32043686e-03f, -1.31959277e-03f, -1.31853498e-03f, - -1.31735687e-03f, -1.31600348e-03f, -1.31447997e-03f, -1.31278203e-03f, -1.31088931e-03f, -1.30884001e-03f, - -1.30664601e-03f, -1.30424467e-03f, -1.30164947e-03f, -1.29893691e-03f, -1.29604380e-03f, -1.29295548e-03f, - -1.28974067e-03f, -1.28628903e-03f, -1.28275127e-03f, -1.27900135e-03f, -1.27512109e-03f, -1.27106817e-03f, - -1.26678664e-03f, -1.26240266e-03f, -1.25784111e-03f, -1.25311541e-03f, -1.24825238e-03f, -1.24315812e-03f, - -1.23802355e-03f, -1.23261700e-03f, -1.22714075e-03f, -1.22143180e-03f, -1.21556001e-03f, -1.20964939e-03f, - -1.20344058e-03f, -1.19720623e-03f, -1.19070242e-03f, -1.18413336e-03f, -1.17737165e-03f, -1.17047352e-03f, - -1.16342628e-03f, -1.15623828e-03f, -1.14894426e-03f, -1.14139471e-03f, -1.13375684e-03f, -1.12602238e-03f, - -1.11813692e-03f, -1.11002525e-03f, -1.10186433e-03f, -1.09351474e-03f, -1.08507331e-03f, -1.07645902e-03f, - -1.06770666e-03f, -1.05886847e-03f, -1.04986665e-03f, -1.04074529e-03f, -1.03147360e-03f, -1.02209708e-03f, - -1.01255007e-03f, -1.00292805e-03f, -9.93161347e-04f, -9.83303098e-04f, -9.73295861e-04f, -9.63162113e-04f, - -9.52925865e-04f, -9.42601285e-04f, -9.32110971e-04f, -9.21540503e-04f, -9.10817211e-04f, -9.00019315e-04f, - -8.89121862e-04f, -8.78128787e-04f, -8.66961352e-04f, -8.55752812e-04f, -8.44389337e-04f, -8.32976434e-04f, - -8.21455092e-04f, -8.09829532e-04f, -7.98113416e-04f, -7.86286097e-04f, -7.74340703e-04f, -7.62386704e-04f, - -7.50298280e-04f, -7.38126234e-04f, -7.25873506e-04f, -7.13479099e-04f, -7.01061264e-04f, -6.88560328e-04f, - -6.75976529e-04f, -6.63304916e-04f, -6.50571273e-04f, -6.37755848e-04f, -6.24863491e-04f, -6.11929437e-04f, - -5.98869135e-04f, -5.85826972e-04f, -5.72635195e-04f, -5.59441585e-04f, -5.46174424e-04f, -5.32801615e-04f, - -5.19404825e-04f, -5.05950954e-04f, -4.92460978e-04f, -4.78917002e-04f, -4.65288416e-04f, -4.51627724e-04f, - -4.37950606e-04f, -4.24207473e-04f, -4.10411250e-04f, -3.96589027e-04f, -3.82752096e-04f, -3.68772204e-04f, - -3.54882609e-04f, -3.40882177e-04f, -3.26883642e-04f, -3.12871471e-04f, -2.98785777e-04f, -2.84722980e-04f, - -2.70584269e-04f, -2.56490009e-04f, -2.42332208e-04f, -2.28161471e-04f, -2.13950277e-04f, -1.99747109e-04f, - -1.85546031e-04f, -1.71343643e-04f, -1.57071747e-04f, -1.42836367e-04f, -1.28619428e-04f, -1.14374212e-04f, - -1.00098891e-04f, -8.58748406e-05f, -7.16130027e-05f, -5.73904689e-05f, -4.31254145e-05f, -2.89455889e-05f, - -1.46959878e-05f, -5.33149755e-07f, 1.37054052e-05f, 2.78574326e-05f, 4.20237257e-05f, 5.61511837e-05f, - 7.02450230e-05f, 8.43594291e-05f, 9.84453799e-05f, 1.12469954e-04f, 1.26482520e-04f, 1.40449684e-04f, - 1.54398619e-04f, 1.68322421e-04f, 1.82209834e-04f, 1.96032041e-04f, 2.09813314e-04f, 2.23594105e-04f, - 2.37311696e-04f, 2.50985918e-04f, 2.64584919e-04f, 2.78181259e-04f, 2.91704144e-04f, 3.05172586e-04f, - 3.18619814e-04f, 3.31954586e-04f, 3.45291027e-04f, 3.58500683e-04f, 3.71727610e-04f, 3.84815197e-04f, - 3.97873281e-04f, 4.10866892e-04f, 4.23835004e-04f, 4.36691369e-04f, 4.49481521e-04f, 4.62190510e-04f, - 4.74832154e-04f, 4.87402579e-04f, 4.99876379e-04f, 5.12299295e-04f, 5.24637289e-04f, 5.36899418e-04f, - 5.49046015e-04f, 5.61159560e-04f, 5.73122613e-04f, 5.85068294e-04f, 5.96869531e-04f, 6.08618958e-04f, - 6.20231676e-04f, 6.31793346e-04f, 6.43215376e-04f, 6.54579304e-04f, 6.65867157e-04f, 6.76998320e-04f, - 6.88058354e-04f, 6.99055755e-04f, 7.09862448e-04f, 7.20605711e-04f, 7.31229488e-04f, 7.41796005e-04f, - 7.52227199e-04f, 7.62526780e-04f, 7.72715316e-04f, 7.82823531e-04f, 7.92817928e-04f, 8.02652870e-04f, - 8.12438756e-04f, 8.22022247e-04f, 8.31562797e-04f, 8.40954818e-04f, 8.50223395e-04f, 8.59389975e-04f, - 8.68411870e-04f, 8.77289973e-04f, 8.86101453e-04f, 8.94748646e-04f, 9.03279300e-04f, 9.11657805e-04f, - 9.19947506e-04f, 9.28100265e-04f, 9.36122139e-04f, 9.43995632e-04f, 9.51703739e-04f, 9.59323147e-04f, - 9.66808702e-04f, 9.74168675e-04f, 9.81372268e-04f, 9.88420756e-04f, 9.95399422e-04f, 1.00215274e-03f, - 1.00879097e-03f, 1.01533940e-03f, 1.02171044e-03f, 1.02798832e-03f, 1.03404714e-03f, 1.03997690e-03f, - 1.04580120e-03f, 1.05143233e-03f, 1.05696666e-03f, 1.06231882e-03f, 1.06757489e-03f, 1.07266995e-03f, - 1.07759360e-03f, 1.08235989e-03f, 1.08698437e-03f, 1.09150050e-03f, 1.09582812e-03f, 1.10002281e-03f, - 1.10405241e-03f, 1.10799856e-03f, 1.11171528e-03f, 1.11528973e-03f, 1.11873885e-03f, 1.12201349e-03f, - 1.12516782e-03f, 1.12815123e-03f, 1.13097113e-03f, 1.13366952e-03f, 1.13617651e-03f, 1.13860682e-03f, - 1.14077697e-03f, 1.14289737e-03f, 1.14478823e-03f, 1.14656867e-03f, 1.14815999e-03f, 1.14960100e-03f, - 1.15094607e-03f, 1.15205565e-03f, 1.15310436e-03f, 1.15391238e-03f, 1.15462283e-03f, 1.15515281e-03f, - 1.15553060e-03f, 1.15580505e-03f, 1.15585198e-03f, 1.15579947e-03f, 1.15553847e-03f, 1.15518578e-03f, - 1.15467149e-03f, 1.15395152e-03f, 1.15312746e-03f, 1.15212526e-03f, 1.15105069e-03f, 1.14974432e-03f, - 1.14831016e-03f, 1.14671036e-03f, 1.14496867e-03f, 1.14306107e-03f, 1.14105694e-03f, 1.13884371e-03f, - 1.13652529e-03f, 1.13406255e-03f, 1.13142445e-03f, 1.12863830e-03f, 1.12571803e-03f, 1.12268367e-03f, - 1.11942930e-03f, 1.11610667e-03f, 1.11257262e-03f, 1.10895936e-03f, 1.10516438e-03f, 1.10125670e-03f, - 1.09717622e-03f, 1.09290895e-03f, 1.08858006e-03f, 1.08411042e-03f, 1.07948022e-03f, 1.07469740e-03f, - 1.06980905e-03f, 1.06478843e-03f, 1.05957723e-03f, 1.05430384e-03f, 1.04883732e-03f, 1.04326661e-03f, - 1.03752212e-03f, 1.03169528e-03f, 1.02576379e-03f, 1.01964593e-03f, 1.01341018e-03f, 1.00700515e-03f, - 1.00057402e-03f, 9.93967937e-04f, 9.87205058e-04f, 9.80378921e-04f, 9.73377903e-04f, 9.66300716e-04f, - 9.59064968e-04f, 9.51718027e-04f, 9.44229192e-04f, 9.36725251e-04f, 9.28982555e-04f, 9.21182787e-04f, - 9.13245231e-04f, 9.05217298e-04f, 8.97077532e-04f, 8.88808426e-04f, 8.80490545e-04f, 8.72019944e-04f, - 8.63412722e-04f, 8.54697575e-04f, 8.45942590e-04f, 8.37049264e-04f, 8.28086308e-04f, 8.18949804e-04f, - 8.09738660e-04f, 8.00447655e-04f, 7.91099374e-04f, 7.81651857e-04f, 7.72026989e-04f, 7.62376729e-04f, - 7.52600763e-04f, 7.42784288e-04f, 7.32846495e-04f, 7.22787935e-04f, 7.12699886e-04f, 7.02505563e-04f, - 6.92217585e-04f, 6.81877275e-04f, 6.71421916e-04f, 6.60961532e-04f, 6.50347829e-04f, 6.39701418e-04f, - 6.28929859e-04f, 6.18134162e-04f, 6.07244327e-04f, 5.96280748e-04f, 5.85287503e-04f, 5.74191281e-04f, - 5.63082706e-04f, 5.51831619e-04f, 5.40577677e-04f, 5.29198325e-04f, 5.17855117e-04f, 5.06405457e-04f, - 4.94863742e-04f, 4.83337181e-04f, 4.71708367e-04f, 4.60101629e-04f, 4.48338069e-04f, 4.36607771e-04f, - 4.24764728e-04f, 4.12973256e-04f, 4.01057626e-04f, 3.89129987e-04f, 3.77166877e-04f, 3.65185403e-04f, - 3.53105855e-04f, 3.41049040e-04f, 3.28889681e-04f, 3.16773460e-04f, 3.04646489e-04f, 2.92412236e-04f, - 2.80195332e-04f, 2.67939711e-04f, 2.55670174e-04f, 2.43379388e-04f, 2.31059777e-04f, 2.18731626e-04f, - 2.06389345e-04f, 1.94017217e-04f, 1.81651799e-04f, 1.69269503e-04f, 1.56837236e-04f, 1.44466564e-04f, - 1.32047404e-04f, 1.19636701e-04f, 1.07220818e-04f, 9.47903169e-05f, 8.23542596e-05f, 6.99558994e-05f, - 5.74733750e-05f, 4.51605184e-05f, 3.27337236e-05f, 2.03389522e-05f, 7.92135976e-06f, -4.47267011e-06f, - -1.67806216e-05f, -2.91607702e-05f, -4.14408746e-05f, -5.38086877e-05f, -6.61043739e-05f, -7.83606282e-05f, - -9.06046657e-05f, -1.02819842e-04f, -1.15052301e-04f, -1.27177495e-04f, -1.39340496e-04f, -1.51446922e-04f, - -1.63531284e-04f, -1.75585011e-04f, -1.87609903e-04f, -1.99555592e-04f, -2.11500348e-04f, -2.23389454e-04f, - -2.35232732e-04f, -2.47057105e-04f, -2.58811231e-04f, -2.70549903e-04f, -2.82219834e-04f, -2.93839149e-04f, - -3.05411999e-04f, -3.16962036e-04f, -3.28369376e-04f, -3.39810215e-04f, -3.51138742e-04f, -3.62459217e-04f, - -3.73704633e-04f, -3.84880078e-04f, -3.95999383e-04f, -4.07002828e-04f, -4.18008373e-04f, -4.28958723e-04f, - -4.39764909e-04f, -4.50622528e-04f, -4.61289390e-04f, -4.71951231e-04f, -4.82508443e-04f, -4.92964760e-04f, - -5.03404816e-04f, -5.13772289e-04f, -5.24036583e-04f, -5.34219610e-04f, -5.44351216e-04f, -5.54307933e-04f, - -5.64259335e-04f, -5.74116706e-04f, -5.83891931e-04f, -5.93586245e-04f, -6.03147878e-04f, -6.12640521e-04f, - -6.22096242e-04f, -6.31374545e-04f, -6.40637989e-04f, -6.49786681e-04f, -6.58823337e-04f, -6.67720647e-04f, - -6.76585881e-04f, -6.85303690e-04f, -6.93997130e-04f, -7.02555857e-04f, -7.10962721e-04f, -7.19321854e-04f, - -7.27566341e-04f, -7.35687145e-04f, -7.43737297e-04f, -7.51617381e-04f, -7.59517083e-04f, -7.67183940e-04f, - -7.74782572e-04f, -7.82252893e-04f, -7.89662294e-04f, -7.96906731e-04f, -8.04105970e-04f, -8.11124747e-04f, - -8.18039994e-04f, -8.24870651e-04f, -8.31552483e-04f, -8.38131149e-04f, -8.44607373e-04f, -8.50945478e-04f, - -8.57183962e-04f, -8.63307229e-04f, -8.69231748e-04f, -8.75123026e-04f, -8.80902184e-04f, -8.86540574e-04f, - -8.92010786e-04f, -8.97403919e-04f, -9.02643875e-04f, -9.07797939e-04f, -9.12749394e-04f, -9.17627053e-04f, - -9.22405779e-04f, -9.27044483e-04f, -9.31550519e-04f, -9.35896083e-04f, -9.40126499e-04f, -9.44254523e-04f, - -9.48276064e-04f, -9.52112320e-04f, -9.55857066e-04f, -9.59460878e-04f, -9.62899052e-04f, -9.66253571e-04f, - -9.69423067e-04f, -9.72543892e-04f, -9.75476558e-04f, -9.78319563e-04f, -9.80955115e-04f, -9.83546407e-04f, - -9.85935775e-04f, -9.88233665e-04f, -9.90373618e-04f, -9.92384334e-04f, -9.94302372e-04f, -9.96039546e-04f, - -9.97675179e-04f, -9.99121685e-04f, -1.00051978e-03f, -1.00170967e-03f, -1.00283257e-03f, -1.00372852e-03f, - -1.00458787e-03f, -1.00529879e-03f, -1.00581417e-03f, -1.00622781e-03f, -1.00656740e-03f, -1.00669857e-03f, - -1.00670603e-03f, -1.00660164e-03f, -1.00636104e-03f, -1.00601222e-03f, -1.00544363e-03f, -1.00482477e-03f, - -1.00405888e-03f, -1.00316927e-03f, -1.00212091e-03f, -1.00096403e-03f, -9.99695320e-04f, -9.98251000e-04f, - -9.96653699e-04f, -9.95026853e-04f, -9.93180868e-04f, -9.91241988e-04f, -9.89131963e-04f, -9.86952105e-04f, - -9.84646823e-04f, -9.82193518e-04f, -9.79586502e-04f, -9.76888356e-04f, -9.74021821e-04f, -9.71085888e-04f, - -9.68009077e-04f, -9.64791922e-04f, -9.61456411e-04f, -9.57981446e-04f, -9.54425371e-04f, -9.50700437e-04f, - -9.46855221e-04f, -9.42937647e-04f, -9.38840471e-04f, -9.34720054e-04f, -9.30383735e-04f, -9.25965499e-04f, - -9.21375581e-04f, -9.16763713e-04f, -9.11991452e-04f, -9.07096324e-04f, -9.02128429e-04f, -8.96945687e-04f, - -8.91761208e-04f, -8.86390139e-04f, -8.80979808e-04f, -8.75370980e-04f, -8.69724015e-04f, -8.63908684e-04f, - -8.58056242e-04f, -8.52057944e-04f, -8.45918038e-04f, -8.39745548e-04f, -8.33431654e-04f, -8.27007586e-04f, - -8.20503410e-04f, -8.13866189e-04f, -8.07149367e-04f, -8.00329671e-04f, -7.93380527e-04f, -7.86399767e-04f, - -7.79279033e-04f, -7.72079448e-04f, -7.64804514e-04f, -7.57387099e-04f, -7.49855690e-04f, -7.42291230e-04f, - -7.34655760e-04f, -7.26897633e-04f, -7.19051858e-04f, -7.11108190e-04f, -7.03099503e-04f, -6.94977691e-04f, - -6.86763827e-04f, -6.78553961e-04f, -6.70175676e-04f, -6.61811745e-04f, -6.53261730e-04f, -6.44653467e-04f, - -6.36031333e-04f, -6.27267184e-04f, -6.18472443e-04f, -6.09535700e-04f, -6.00674523e-04f, -5.91606335e-04f, - -5.82514012e-04f, -5.73360184e-04f, -5.64115353e-04f, -5.54903681e-04f, -5.45489223e-04f, -5.36095444e-04f, - -5.26594323e-04f, -5.17090194e-04f, -5.07493833e-04f, -4.97796033e-04f, -4.88118236e-04f, -4.78351902e-04f, - -4.68570147e-04f, -4.58668109e-04f, -4.48749163e-04f, -4.38795358e-04f, -4.28797375e-04f, -4.18755808e-04f, - -4.08630668e-04f, -3.98460152e-04f, -3.88295003e-04f, -3.78058544e-04f, -3.67759900e-04f, -3.57497922e-04f, - -3.47139560e-04f, -3.36775030e-04f, -3.26379240e-04f, -3.15903012e-04f, -3.05386662e-04f, -2.94921403e-04f, - -2.84393128e-04f, -2.73863506e-04f, -2.63270729e-04f, -2.52626370e-04f, -2.42017621e-04f, -2.31331315e-04f, - -2.20690965e-04f, -2.10011861e-04f, -1.99266056e-04f, -1.88571410e-04f, -1.77830585e-04f, -1.67058054e-04f, - -1.56348657e-04f, -1.45562470e-04f, -1.34828139e-04f, -1.23989304e-04f, -1.13229356e-04f, -1.02384844e-04f, - -9.16421695e-05f, -8.08375495e-05f, -7.00411245e-05f, -5.92613889e-05f, -4.84458034e-05f, -3.76545651e-05f, - -2.68951326e-05f, -1.61449344e-05f, -5.33969566e-06f, 5.40477619e-06f, 1.61356956e-05f, 2.68616096e-05f, - 3.75556053e-05f, 4.82709069e-05f, 5.89155560e-05f, 6.96147018e-05f, 8.02503272e-05f, 9.08797354e-05f, - 1.01455022e-04f, 1.12022643e-04f, 1.22581567e-04f, 1.33129256e-04f, 1.43583690e-04f, 1.54035564e-04f, - 1.64490175e-04f, 1.74881956e-04f, 1.85248909e-04f, 1.95551333e-04f, 2.05879650e-04f, 2.16094808e-04f, - 2.26329896e-04f, 2.36509742e-04f, 2.46628591e-04f, 2.56756587e-04f, 2.66775007e-04f, 2.76799949e-04f, - 2.86713853e-04f, 2.96638019e-04f, 3.06501046e-04f, 3.16317101e-04f, 3.26065852e-04f, 3.35751867e-04f, - 3.45411735e-04f, 3.54997904e-04f, 3.64537957e-04f, 3.74020878e-04f, 3.83431871e-04f, 3.92818810e-04f, - 4.02080892e-04f, 4.11342270e-04f, 4.20474587e-04f, 4.29611359e-04f, 4.38664182e-04f, 4.47624030e-04f, - 4.56544889e-04f, 4.65329070e-04f, 4.74145226e-04f, 4.82788124e-04f, 4.91499860e-04f, 5.00010026e-04f, - 5.08434428e-04f, 5.16879624e-04f, 5.25210692e-04f, 5.33442384e-04f, 5.41585842e-04f, 5.49673504e-04f, - 5.57712394e-04f, 5.65652548e-04f, 5.73435560e-04f, 5.81207432e-04f, 5.88897357e-04f, 5.96486341e-04f, - 6.03958325e-04f, 6.11399527e-04f, 6.18709102e-04f, 6.25947906e-04f, 6.33121138e-04f, 6.40153672e-04f, - 6.47113753e-04f, 6.53987844e-04f, 6.60781623e-04f, 6.67481605e-04f, 6.74050732e-04f, 6.80563583e-04f, - 6.86952692e-04f, 6.93239088e-04f, 6.99445319e-04f, 7.05535282e-04f, 7.11579570e-04f, 7.17478949e-04f, - 7.23303505e-04f, 7.28980993e-04f, 7.34588034e-04f, 7.40101420e-04f, 7.45505802e-04f, 7.50785385e-04f, - 7.55987557e-04f, 7.61057969e-04f, 7.66033481e-04f, 7.70903458e-04f, 7.75698687e-04f, 7.80328594e-04f, - 7.84905857e-04f, 7.89367585e-04f, 7.93696698e-04f, 7.97930628e-04f, 8.02051865e-04f, 8.06049385e-04f, - 8.09936040e-04f, 8.13746346e-04f, 8.17379531e-04f, 8.20990683e-04f, 8.24432294e-04f, 8.27795386e-04f, - 8.31000607e-04f, 8.34156818e-04f, 8.37101307e-04f, 8.40030039e-04f, 8.42804648e-04f, 8.45490820e-04f, - 8.48016660e-04f, 8.50467118e-04f, 8.52767701e-04f, 8.54961489e-04f, 8.57097538e-04f, 8.59058692e-04f, - 8.60956046e-04f, 8.62671840e-04f, 8.64325048e-04f, 8.65800178e-04f, 8.67224064e-04f, 8.68505938e-04f, - 8.69689824e-04f, 8.70744278e-04f, 8.71684805e-04f, 8.72503658e-04f, 8.73216144e-04f, 8.73807886e-04f, - 8.74296741e-04f, 8.74661209e-04f, 8.74923970e-04f, 8.75014183e-04f, 8.75020824e-04f, 8.74944651e-04f, - 8.74777493e-04f, 8.74400442e-04f, 8.73963794e-04f, 8.73419002e-04f, 8.72769637e-04f, 8.71979276e-04f, - 8.71049664e-04f, 8.70014383e-04f, 8.68933581e-04f, 8.67684390e-04f, 8.66344915e-04f, 8.64841325e-04f, - 8.63286723e-04f, 8.61592833e-04f, 8.59830652e-04f, 8.57900720e-04f, 8.55853821e-04f, 8.53768075e-04f, - 8.51458434e-04f, 8.49144495e-04f, 8.46687935e-04f, 8.44124895e-04f, 8.41477241e-04f, 8.38600725e-04f, - 8.35799842e-04f, 8.32721845e-04f, 8.29675611e-04f, 8.26452543e-04f, 8.23125062e-04f, 8.19727206e-04f, - 8.16140526e-04f, 8.12602880e-04f, 8.08781307e-04f, 8.05013822e-04f, 8.01023017e-04f, 7.97052052e-04f, - 7.92882212e-04f, 7.88622668e-04f, 7.84290453e-04f, 7.79867965e-04f, 7.75307098e-04f, 7.70744758e-04f, - 7.65943271e-04f, 7.61158792e-04f, 7.56223942e-04f, 7.51222657e-04f, 7.46122005e-04f, 7.40891688e-04f, - 7.35642985e-04f, 7.30256620e-04f, 7.24755543e-04f, 7.19215058e-04f, 7.13534617e-04f, 7.07828208e-04f, - 7.01976472e-04f, 6.96104541e-04f, 6.90062828e-04f, 6.84010239e-04f, 6.77853426e-04f, 6.71568752e-04f, - 6.65306643e-04f, 6.58837817e-04f, 6.52377306e-04f, 6.45802888e-04f, 6.39154365e-04f, 6.32421675e-04f, - 6.25639707e-04f, 6.18758535e-04f, 6.11813257e-04f, 6.04791463e-04f, 5.97701837e-04f, 5.90484036e-04f, - 5.83303601e-04f, 5.75968090e-04f, 5.68635196e-04f, 5.61161035e-04f, 5.53637194e-04f, 5.46128317e-04f, - 5.38483810e-04f, 5.30778114e-04f, 5.23006566e-04f, 5.15205240e-04f, 5.07313917e-04f, 4.99353405e-04f, - 4.91395269e-04f, 4.83321160e-04f, 4.75222629e-04f, 4.67046910e-04f, 4.58847913e-04f, 4.50584677e-04f, - 4.42283177e-04f, 4.33898103e-04f, 4.25518954e-04f, 4.17036699e-04f, 4.08550557e-04f, 3.99970518e-04f, - 3.91395172e-04f, 3.82734758e-04f, 3.74054308e-04f, 3.65361588e-04f, 3.56594974e-04f, 3.47818276e-04f, - 3.38956168e-04f, 3.30117725e-04f, 3.21171760e-04f, 3.12332043e-04f, 3.03282221e-04f, 2.94290766e-04f, - 2.85300024e-04f, 2.76235319e-04f, 2.67156463e-04f, 2.58038036e-04f, 2.48914512e-04f, 2.39768713e-04f, - 2.30598161e-04f, 2.21387245e-04f, 2.12183131e-04f, 2.02939044e-04f, 1.93712949e-04f, 1.84437752e-04f, - 1.75154395e-04f, 1.65832984e-04f, 1.56559861e-04f, 1.47231501e-04f, 1.37923421e-04f, 1.28570540e-04f, - 1.19234156e-04f, 1.09869654e-04f, 1.00547484e-04f, 9.11741137e-05f, 8.18104201e-05f, 7.24690192e-05f, - 6.30970825e-05f, 5.37434745e-05f, 4.43997770e-05f, 3.50573796e-05f, 2.57081387e-05f, 1.63689307e-05f, - 7.00205213e-06f, -2.30852565e-06f, -1.16481396e-05f, -2.09062985e-05f, -3.01929239e-05f, -3.94972186e-05f, - -4.87296064e-05f, -5.79899014e-05f, -6.72048709e-05f, -7.64419554e-05f, -8.55984837e-05f, -9.47926838e-05f, - -1.03904573e-04f, -1.13017806e-04f, -1.22148297e-04f, -1.31198621e-04f, -1.40222392e-04f, -1.49291056e-04f, - -1.58255432e-04f, -1.67231582e-04f, -1.76152516e-04f, -1.85029901e-04f, -1.93893344e-04f, -2.02735756e-04f, - -2.11527491e-04f, -2.20281149e-04f, -2.29008362e-04f, -2.37645500e-04f, -2.46315538e-04f, -2.54888715e-04f, - -2.63481513e-04f, -2.71970004e-04f, -2.80432534e-04f, -2.88859669e-04f, -2.97224812e-04f, -3.05554463e-04f, - -3.13800750e-04f, -3.22033442e-04f, -3.30215174e-04f, -3.38368803e-04f, -3.46396593e-04f, -3.54431039e-04f, - -3.62381093e-04f, -3.70313238e-04f, -3.78151855e-04f, -3.85908918e-04f, -3.93654637e-04f, -4.01347264e-04f, - -4.09003830e-04f, -4.16489479e-04f, -4.23986520e-04f, -4.31388067e-04f, -4.38761220e-04f, -4.46078549e-04f, - -4.53285895e-04f, -4.60467120e-04f, -4.67513795e-04f, -4.74584185e-04f, -4.81520963e-04f, -4.88468888e-04f, - -4.95207711e-04f, -5.01982897e-04f, -5.08615341e-04f, -5.15209675e-04f, -5.21740629e-04f, -5.28197205e-04f, - -5.34577124e-04f, -5.40834269e-04f, -5.47066362e-04f, -5.53216060e-04f, -5.59238292e-04f, -5.65213921e-04f, - -5.71147563e-04f, -5.76968040e-04f, -5.82705358e-04f, -5.88337026e-04f, -5.93903813e-04f, -5.99365147e-04f, - -6.04778657e-04f, -6.10096733e-04f, -6.15323122e-04f, -6.20451240e-04f, -6.25547193e-04f, -6.30488128e-04f, - -6.35360531e-04f, -6.40149019e-04f, -6.44865066e-04f, -6.49474585e-04f, -6.54028679e-04f, -6.58450705e-04f, - -6.62769490e-04f, -6.67040883e-04f, -6.71191379e-04f, -6.75258143e-04f, -6.79208274e-04f, -6.83107032e-04f, - -6.86893270e-04f, -6.90573984e-04f, -6.94208145e-04f, -6.97691786e-04f, -7.01116382e-04f, -7.04382138e-04f, - -7.07647899e-04f, -7.10740607e-04f, -7.13777787e-04f, -7.16681190e-04f, -7.19518595e-04f, -7.22276563e-04f, - -7.24903015e-04f, -7.27457283e-04f, -7.29872457e-04f, -7.32217939e-04f, -7.34458166e-04f, -7.36595075e-04f, - -7.38630136e-04f, -7.40593237e-04f, -7.42416678e-04f, -7.44212893e-04f, -7.45802877e-04f, -7.47355113e-04f, - -7.48832483e-04f, -7.50139280e-04f, -7.51403297e-04f, -7.52618197e-04f, -7.53595879e-04f, -7.54565577e-04f, - -7.55440010e-04f, -7.56157519e-04f, -7.56824976e-04f, -7.57373774e-04f, -7.57823441e-04f, -7.58162369e-04f, - -7.58405026e-04f, -7.58583689e-04f, -7.58595347e-04f, -7.58606048e-04f, -7.58371059e-04f, -7.58176029e-04f, - -7.57824622e-04f, -7.57385478e-04f, -7.56830136e-04f, -7.56186182e-04f, -7.55485138e-04f, -7.54611503e-04f, - -7.53648656e-04f, -7.52585636e-04f, -7.51510583e-04f, -7.50270202e-04f, -7.48969297e-04f, -7.47529491e-04f, - -7.45962784e-04f, -7.44368271e-04f, -7.42625678e-04f, -7.40839719e-04f, -7.38977458e-04f, -7.36942220e-04f, - -7.34876300e-04f, -7.32653372e-04f, -7.30376125e-04f, -7.27973280e-04f, -7.25531917e-04f, -7.22974985e-04f, - -7.20313083e-04f, -7.17576478e-04f, -7.14731800e-04f, -7.11852637e-04f, -7.08793047e-04f, -7.05686163e-04f, - -7.02499964e-04f, -6.99189467e-04f, -6.95854814e-04f, -6.92353479e-04f, -6.88805027e-04f, -6.85192776e-04f, - -6.81486057e-04f, -6.77640429e-04f, -6.73784580e-04f, -6.69824909e-04f, -6.65736480e-04f, -6.61574617e-04f, - -6.57365448e-04f, -6.53068828e-04f, -6.48705637e-04f, -6.44196335e-04f, -6.39650098e-04f, -6.35029309e-04f, - -6.30280078e-04f, -6.25563704e-04f, -6.20678133e-04f, -6.15799865e-04f, -6.10761799e-04f, -6.05658813e-04f, - -6.00468598e-04f, -5.95238806e-04f, -5.89976771e-04f, -5.84584219e-04f, -5.79110609e-04f, -5.73605189e-04f, - -5.67999880e-04f, -5.62360707e-04f, -5.56600118e-04f, -5.50852222e-04f, -5.44983185e-04f, -5.39062090e-04f, - -5.33043673e-04f, -5.27046254e-04f, -5.20937493e-04f, -5.14732685e-04f, -5.08514255e-04f, -5.02161166e-04f, - -4.95884715e-04f, -4.89373245e-04f, -4.82975626e-04f, -4.76384788e-04f, -4.69851683e-04f, -4.63193368e-04f, - -4.56490901e-04f, -4.49750527e-04f, -4.42957462e-04f, -4.36124127e-04f, -4.29199662e-04f, -4.22264628e-04f, - -4.15256963e-04f, -4.08241987e-04f, -4.01147612e-04f, -3.93989949e-04f, -3.86817772e-04f, -3.79579783e-04f, - -3.72331966e-04f, -3.65036244e-04f, -3.57702242e-04f, -3.50273540e-04f, -3.42876766e-04f, -3.35408499e-04f, - -3.27920449e-04f, -3.20365416e-04f, -3.12815083e-04f, -3.05235770e-04f, -2.97582271e-04f, -2.89927532e-04f, - -2.82234740e-04f, -2.74512862e-04f, -2.66783521e-04f, -2.58972809e-04f, -2.51182347e-04f, -2.43359336e-04f, - -2.35499784e-04f, -2.27628297e-04f, -2.19750638e-04f, -2.11837779e-04f, -2.03859207e-04f, -1.95951266e-04f, - -1.87958576e-04f, -1.79958873e-04f, -1.71992410e-04f, -1.63983925e-04f, -1.55910414e-04f, -1.47898136e-04f, - -1.39841339e-04f, -1.31780838e-04f, -1.23703734e-04f, -1.15655219e-04f, -1.07526273e-04f, -9.94464402e-05f, - -9.13870214e-05f, -8.32619580e-05f, -7.51481947e-05f, -6.70450780e-05f, -5.89161281e-05f, -5.08423349e-05f, - -4.27624587e-05f, -3.46525627e-05f, -2.65438198e-05f, -1.84667436e-05f, -1.03738154e-05f, -2.30956439e-06f, - 5.77631242e-06f, 1.38485966e-05f, 2.18436752e-05f, 2.99309406e-05f, 3.79346610e-05f, 4.59682663e-05f, - 5.39510401e-05f, 6.19234684e-05f, 6.99008233e-05f, 7.78777415e-05f, 8.57810874e-05f, 9.36957665e-05f, - 1.01582928e-04f, 1.09466047e-04f, 1.17264850e-04f, 1.25153262e-04f, 1.32892445e-04f, 1.40714550e-04f, - 1.48399602e-04f, 1.56174470e-04f, 1.63824673e-04f, 1.71547032e-04f, 1.79149940e-04f, 1.86752832e-04f, - 1.94299636e-04f, 2.01814347e-04f, 2.09371304e-04f, 2.16789995e-04f, 2.24259700e-04f, 2.31587707e-04f, - 2.39002847e-04f, 2.46296619e-04f, 2.53585020e-04f, 2.60792297e-04f, 2.68006339e-04f, 2.75159355e-04f, - 2.82259306e-04f, 2.89318816e-04f, 2.96339147e-04f, 3.03300158e-04f, 3.10244613e-04f, 3.17096647e-04f, - 3.23924793e-04f, 3.30726718e-04f, 3.37420799e-04f, 3.44109804e-04f, 3.50730904e-04f, 3.57283395e-04f, - 3.63831714e-04f, 3.70287749e-04f, 3.76724361e-04f, 3.83068995e-04f, 3.89337150e-04f, 3.95589025e-04f, - 4.01791236e-04f, 4.07854076e-04f, 4.13946766e-04f, 4.19974060e-04f, 4.25905940e-04f, 4.31799741e-04f, - 4.37550496e-04f, 4.43335428e-04f, 4.49049835e-04f, 4.54625125e-04f, 4.60233127e-04f, 4.65686607e-04f, - 4.71154754e-04f, 4.76504467e-04f, 4.81772212e-04f, 4.87000426e-04f, 4.92134415e-04f, 4.97237855e-04f, - 5.02236772e-04f, 5.07199948e-04f, 5.12065762e-04f, 5.16882254e-04f, 5.21608146e-04f, 5.26245529e-04f, - 5.30790356e-04f, 5.35334011e-04f, 5.39765529e-04f, 5.44147424e-04f, 5.48376773e-04f, 5.52596569e-04f, - 5.56740303e-04f, 5.60790506e-04f, 5.64740943e-04f, 5.68614663e-04f, 5.72467151e-04f, 5.76199198e-04f, - 5.79862761e-04f, 5.83419014e-04f, 5.86922659e-04f, 5.90360970e-04f, 5.93682522e-04f, 5.96908933e-04f, - 6.00137680e-04f, 6.03224523e-04f, 6.06252387e-04f, 6.09142414e-04f, 6.12011927e-04f, 6.14760785e-04f, - 6.17445443e-04f, 6.20062466e-04f, 6.22522519e-04f, 6.24977742e-04f, 6.27346015e-04f, 6.29576819e-04f, - 6.31771339e-04f, 6.33828430e-04f, 6.35888292e-04f, 6.37772007e-04f, 6.39623762e-04f, 6.41355465e-04f, - 6.43001499e-04f, 6.44604927e-04f, 6.46093637e-04f, 6.47508668e-04f, 6.48845962e-04f, 6.50039826e-04f, - 6.51216327e-04f, 6.52255113e-04f, 6.53239779e-04f, 6.54141129e-04f, 6.54964760e-04f, 6.55646042e-04f, - 6.56286567e-04f, 6.56802602e-04f, 6.57281077e-04f, 6.57632239e-04f, 6.57939020e-04f, 6.58135634e-04f, - 6.58214330e-04f, 6.58277836e-04f, 6.58201792e-04f, 6.58060054e-04f, 6.57823896e-04f, 6.57487498e-04f, - 6.57126836e-04f, 6.56620727e-04f, 6.56034059e-04f, 6.55403993e-04f, 6.54584800e-04f, 6.53810069e-04f, - 6.52904562e-04f, 6.51894090e-04f, 6.50773483e-04f, 6.49652319e-04f, 6.48374997e-04f, 6.47071588e-04f, - 6.45681033e-04f, 6.44103241e-04f, 6.42566774e-04f, 6.40883131e-04f, 6.39140710e-04f, 6.37320692e-04f, - 6.35385760e-04f, 6.33428887e-04f, 6.31366488e-04f, 6.29213439e-04f, 6.26965617e-04f, 6.24633507e-04f, - 6.22243342e-04f, 6.19812614e-04f, 6.17246700e-04f, 6.14581132e-04f, 6.11939850e-04f, 6.09122001e-04f, - 6.06265758e-04f, 6.03335090e-04f, 6.00313258e-04f, 5.97277721e-04f, 5.94113656e-04f, 5.90871924e-04f, - 5.87553923e-04f, 5.84150284e-04f, 5.80734091e-04f, 5.77185942e-04f, 5.73565873e-04f, 5.69952902e-04f, - 5.66174616e-04f, 5.62371671e-04f, 5.58474408e-04f, 5.54545699e-04f, 5.50514922e-04f, 5.46456005e-04f, - 5.42311504e-04f, 5.38069488e-04f, 5.33800630e-04f, 5.29423722e-04f, 5.25018470e-04f, 5.20556313e-04f, - 5.16004593e-04f, 5.11398290e-04f, 5.06759957e-04f, 5.02006992e-04f, 4.97227493e-04f, 4.92363902e-04f, - 4.87473888e-04f, 4.82496913e-04f, 4.77485972e-04f, 4.72386736e-04f, 4.67254528e-04f, 4.62059667e-04f, - 4.56810518e-04f, 4.51499032e-04f, 4.46175602e-04f, 4.40718446e-04f, 4.35306826e-04f, 4.29798798e-04f, - 4.24213697e-04f, 4.18597535e-04f, 4.12916574e-04f, 4.07241450e-04f, 4.01456526e-04f, 3.95674467e-04f, - 3.89798950e-04f, 3.83944586e-04f, 3.77973781e-04f, 3.72005764e-04f, 3.65984207e-04f, 3.59908584e-04f, - 3.53796629e-04f, 3.47686299e-04f, 3.41506585e-04f, 3.35275863e-04f, 3.28983699e-04f, 3.22682149e-04f, - 3.16374523e-04f, 3.10010678e-04f, 3.03593671e-04f, 2.97151470e-04f, 2.90721423e-04f, 2.84206717e-04f, - 2.77672965e-04f, 2.71083436e-04f, 2.64523910e-04f, 2.57913455e-04f, 2.51266250e-04f, 2.44591816e-04f, - 2.37931736e-04f, 2.31214713e-04f, 2.24453181e-04f, 2.17655070e-04f, 2.10938227e-04f, 2.04089359e-04f, - 1.97305280e-04f, 1.90450751e-04f, 1.83578232e-04f, 1.76696701e-04f, 1.69763494e-04f, 1.62917356e-04f, - 1.55960898e-04f, 1.49093219e-04f, 1.42084338e-04f, 1.35126566e-04f, 1.28158621e-04f, 1.21184220e-04f, - 1.14213295e-04f, 1.07212812e-04f, 1.00199819e-04f, 9.32202594e-05f, 8.61614733e-05f, 7.91332115e-05f, - 7.21590694e-05f, 6.51124493e-05f, 5.81061148e-05f, 5.10636021e-05f, 4.40116363e-05f, 3.70143676e-05f, - 3.00055209e-05f, 2.29886879e-05f, 1.59835670e-05f, 8.94363553e-06f, 1.95168976e-06f, -5.04207166e-06f, - -1.20216650e-05f, -1.90317419e-05f, -2.59491708e-05f, -3.29478596e-05f, -3.98759663e-05f, -4.68165741e-05f, - -5.37181507e-05f, -6.06467127e-05f, -6.75669688e-05f, -7.44141273e-05f, -8.13127985e-05f, -8.80880382e-05f, - -9.49649471e-05f, -1.01750359e-04f, -1.08524759e-04f, -1.15312606e-04f, -1.22017290e-04f, -1.28779196e-04f, - -1.35452870e-04f, -1.42104727e-04f, -1.48746009e-04f, -1.55392595e-04f, -1.62001869e-04f, -1.68542468e-04f, - -1.75077233e-04f, -1.81612997e-04f, -1.88093648e-04f, -1.94513171e-04f, -2.00932325e-04f, -2.07296975e-04f, - -2.13658057e-04f, -2.19960283e-04f, -2.26229588e-04f, -2.32520052e-04f, -2.38697947e-04f, -2.44849494e-04f, - -2.50971437e-04f, -2.57074718e-04f, -2.63141211e-04f, -2.69125850e-04f, -2.75131592e-04f, -2.80980662e-04f, - -2.86966583e-04f, -2.92740312e-04f, -2.98578138e-04f, -3.04272790e-04f, -3.10054830e-04f, -3.15651834e-04f, - -3.21301544e-04f, -3.26835839e-04f, -3.32365900e-04f, -3.37870316e-04f, -3.43234162e-04f, -3.48617343e-04f, - -3.53936005e-04f, -3.59210509e-04f, -3.64451861e-04f, -3.69544228e-04f, -3.74708083e-04f, -3.79737040e-04f, - -3.84789449e-04f, -3.89722501e-04f, -3.94568730e-04f, -3.99387098e-04f, -4.04174275e-04f, -4.08932725e-04f, - -4.13554110e-04f, -4.18178644e-04f, -4.22679670e-04f, -4.27189803e-04f, -4.31614020e-04f, -4.35989032e-04f, - -4.40300273e-04f, -4.44487514e-04f, -4.48681906e-04f, -4.52792780e-04f, -4.56824225e-04f, -4.60883285e-04f, - -4.64729731e-04f, -4.68624328e-04f, -4.72385104e-04f, -4.76123704e-04f, -4.79813164e-04f, -4.83382643e-04f, - -4.86937657e-04f, -4.90397532e-04f, -4.93763607e-04f, -4.97102880e-04f, -5.00356372e-04f, -5.03564026e-04f, - -5.06676041e-04f, -5.09732761e-04f, -5.12723639e-04f, -5.15599380e-04f, -5.18505995e-04f, -5.21199631e-04f, - -5.23910931e-04f, -5.26560615e-04f, -5.29124843e-04f, -5.31640181e-04f, -5.34018236e-04f, -5.36381983e-04f, - -5.38644720e-04f, -5.40837594e-04f, -5.42966239e-04f, -5.45019914e-04f, -5.47027731e-04f, -5.48919695e-04f, - -5.50779480e-04f, -5.52455557e-04f, -5.54222965e-04f, -5.55778693e-04f, -5.57379091e-04f, -5.58799415e-04f, - -5.60208976e-04f, -5.61490172e-04f, -5.62736371e-04f, -5.63922471e-04f, -5.65018560e-04f, -5.66054877e-04f, - -5.67002405e-04f, -5.67805411e-04f, -5.68667770e-04f, -5.69311427e-04f, -5.70005811e-04f, -5.70559376e-04f, - -5.71057622e-04f, -5.71461684e-04f, -5.71837331e-04f, -5.72068895e-04f, -5.72273403e-04f, -5.72408605e-04f, - -5.72453398e-04f, -5.72428763e-04f, -5.72289454e-04f, -5.72143149e-04f, -5.71880325e-04f, -5.71541964e-04f, - -5.71106825e-04f, -5.70678779e-04f, -5.70127019e-04f, -5.69520277e-04f, -5.68826239e-04f, -5.68008482e-04f, - -5.67181733e-04f, -5.66286039e-04f, -5.65287542e-04f, -5.64219262e-04f, -5.63067573e-04f, -5.61885740e-04f, - -5.60567923e-04f, -5.59273805e-04f, -5.57824705e-04f, -5.56360927e-04f, -5.54759421e-04f, -5.53160910e-04f, - -5.51439788e-04f, -5.49676192e-04f, -5.47799115e-04f, -5.45900681e-04f, -5.43915001e-04f, -5.41856563e-04f, - -5.39702190e-04f, -5.37529352e-04f, -5.35298675e-04f, -5.33002737e-04f, -5.30590205e-04f, -5.28140672e-04f, - -5.25595373e-04f, -5.23026245e-04f, -5.20331921e-04f, -5.17621057e-04f, -5.14834867e-04f, -5.11989960e-04f, - -5.09070469e-04f, -5.06101615e-04f, -5.03035513e-04f, -4.99983134e-04f, -4.96772429e-04f, -4.93610932e-04f, - -4.90266438e-04f, -4.86888208e-04f, -4.83511294e-04f, -4.80049207e-04f, -4.76536318e-04f, -4.72909746e-04f, - -4.69319892e-04f, -4.65589598e-04f, -4.61840089e-04f, -4.57992044e-04f, -4.54101477e-04f, -4.50245964e-04f, - -4.46251625e-04f, -4.42216583e-04f, -4.38111308e-04f, -4.33979466e-04f, -4.29794700e-04f, -4.25517747e-04f, - -4.21235006e-04f, -4.16872886e-04f, -4.12486478e-04f, -4.08054156e-04f, -4.03542692e-04f, -3.99044253e-04f, - -3.94365295e-04f, -3.89759710e-04f, -3.85102907e-04f, -3.80394507e-04f, -3.75571907e-04f, -3.70736296e-04f, - -3.65909899e-04f, -3.61019889e-04f, -3.56028945e-04f, -3.51063689e-04f, -3.45987052e-04f, -3.40983529e-04f, - -3.35852615e-04f, -3.30706377e-04f, -3.25509889e-04f, -3.20276966e-04f, -3.15063843e-04f, -3.09749271e-04f, - -3.04432989e-04f, -2.99031946e-04f, -2.93643848e-04f, -2.88178134e-04f, -2.82745361e-04f, -2.77252628e-04f, - -2.71689943e-04f, -2.66184840e-04f, -2.60563380e-04f, -2.54952870e-04f, -2.49323981e-04f, -2.43607251e-04f, - -2.37939291e-04f, -2.32255428e-04f, -2.26521474e-04f, -2.20703736e-04f, -2.14924031e-04f, -2.09107502e-04f, - -2.03262927e-04f, -1.97404075e-04f, -1.91543420e-04f, -1.85647573e-04f, -1.79702578e-04f, -1.73789481e-04f, - -1.67832289e-04f, -1.61871458e-04f, -1.55898817e-04f, -1.49873250e-04f, -1.43867588e-04f, -1.37881215e-04f, - -1.31816269e-04f, -1.25765358e-04f, -1.19739164e-04f, -1.13645678e-04f, -1.07594848e-04f, -1.01456386e-04f, - -9.53749536e-05f, -8.92794505e-05f, -8.32239150e-05f, -7.70988348e-05f, -7.10119707e-05f, -6.48546933e-05f, - -5.87312866e-05f, -5.26145505e-05f, -4.64867142e-05f, -4.03751657e-05f, -3.42405144e-05f, -2.81133368e-05f, - -2.20168897e-05f, -1.59002130e-05f, -9.78024775e-06f, -3.68133963e-06f, 2.43966983e-06f, 8.51857454e-06f, - 1.46166518e-05f, 2.06590398e-05f, 2.68067056e-05f, 3.27813797e-05f, 3.89001951e-05f, 4.49201995e-05f, - 5.10035386e-05f, 5.69675506e-05f, 6.29550545e-05f, 6.89504144e-05f, 7.49299058e-05f, 8.09076832e-05f, - 8.68491005e-05f, 9.27942288e-05f, 9.86863674e-05f, 1.04581789e-04f, 1.10488197e-04f, 1.16251278e-04f, - 1.22151248e-04f, 1.27929896e-04f, 1.33754512e-04f, 1.39525202e-04f, 1.45279681e-04f, 1.50976540e-04f, - 1.56669168e-04f, 1.62345120e-04f, 1.67981398e-04f, 1.73600643e-04f, 1.79162514e-04f, 1.84747375e-04f, - 1.90270476e-04f, 1.95801347e-04f, 2.01221086e-04f, 2.06694645e-04f, 2.12078875e-04f, 2.17444559e-04f, - 2.22797970e-04f, 2.28126270e-04f, 2.33380159e-04f, 2.38601064e-04f, 2.43847959e-04f, 2.48974863e-04f, - 2.54105757e-04f, 2.59205281e-04f, 2.64225687e-04f, 2.69291060e-04f, 2.74201067e-04f, 2.79175910e-04f, - 2.84068045e-04f, 2.88914569e-04f, 2.93725413e-04f, 2.98506654e-04f, 3.03220122e-04f, 3.07872929e-04f, - 3.12524005e-04f, 3.17100565e-04f, 3.21677608e-04f, 3.26162476e-04f, 3.30588020e-04f, 3.35028701e-04f, - 3.39359791e-04f, 3.43695890e-04f, 3.47926810e-04f, 3.52159313e-04f, 3.56312262e-04f, 3.60442508e-04f, - 3.64489290e-04f, 3.68494766e-04f, 3.72464882e-04f, 3.76393871e-04f, 3.80236402e-04f, 3.84017301e-04f, - 3.87779555e-04f, 3.91464636e-04f, 3.95123846e-04f, 3.98693310e-04f, 4.02215906e-04f, 4.05697452e-04f, - 4.09134612e-04f, 4.12512088e-04f, 4.15794527e-04f, 4.19046809e-04f, 4.22204312e-04f, 4.25385772e-04f, - 4.28471166e-04f, 4.31455007e-04f, 4.34428651e-04f, 4.37338382e-04f, 4.40197677e-04f, 4.42972500e-04f, - 4.45701337e-04f, 4.48335585e-04f, 4.50951280e-04f, 4.53516550e-04f, 4.55934822e-04f, 4.58366421e-04f, - 4.60752201e-04f, 4.63087421e-04f, 4.65278168e-04f, 4.67467706e-04f, 4.69520840e-04f, 4.71589394e-04f, - 4.73579634e-04f, 4.75506954e-04f, 4.77361886e-04f, 4.79184494e-04f, 4.80861420e-04f, 4.82527955e-04f, - 4.84148634e-04f, 4.85689779e-04f, 4.87153823e-04f, 4.88557207e-04f, 4.89912371e-04f, 4.91186609e-04f, - 4.92411773e-04f, 4.93528203e-04f, 4.94645422e-04f, 4.95639951e-04f, 4.96604670e-04f, 4.97496721e-04f, - 4.98313340e-04f, 4.99107642e-04f, 4.99782215e-04f, 5.00380427e-04f, 5.00984743e-04f, 5.01474255e-04f, - 5.01882311e-04f, 5.02261112e-04f, 5.02595745e-04f, 5.02811674e-04f, 5.02973197e-04f, 5.03079999e-04f, - 5.03112141e-04f, 5.03101157e-04f, 5.03009047e-04f, 5.02852731e-04f, 5.02651189e-04f, 5.02332319e-04f, - 5.01974995e-04f, 5.01563859e-04f, 5.01120308e-04f, 5.00566873e-04f, 4.99968687e-04f, 4.99264611e-04f, - 4.98543673e-04f, 4.97747884e-04f, 4.96829955e-04f, 4.95981100e-04f, 4.94980841e-04f, 4.93920981e-04f, - 4.92793650e-04f, 4.91625607e-04f, 4.90357374e-04f, 4.89113081e-04f, 4.87660627e-04f, 4.86296870e-04f, - 4.84807100e-04f, 4.83252704e-04f, 4.81619009e-04f, 4.79910255e-04f, 4.78204151e-04f, 4.76401100e-04f, - 4.74564058e-04f, 4.72647331e-04f, 4.70685502e-04f, 4.68668707e-04f, 4.66563520e-04f, 4.64414890e-04f, - 4.62206634e-04f, 4.59950762e-04f, 4.57611707e-04f, 4.55234922e-04f, 4.52768598e-04f, 4.50301005e-04f, - 4.47723352e-04f, 4.45142974e-04f, 4.42482732e-04f, 4.39771593e-04f, 4.37019578e-04f, 4.34146558e-04f, - 4.31290535e-04f, 4.28349646e-04f, 4.25413399e-04f, 4.22317122e-04f, 4.19291053e-04f, 4.16099971e-04f, - 4.12922829e-04f, 4.09650924e-04f, 4.06387459e-04f, 4.03068816e-04f, 3.99662452e-04f, 3.96206624e-04f, - 3.92783217e-04f, 3.89186413e-04f, 3.85602050e-04f, 3.81974765e-04f, 3.78300356e-04f, 3.74585460e-04f, - 3.70807871e-04f, 3.67019737e-04f, 3.63122834e-04f, 3.59251885e-04f, 3.55268700e-04f, 3.51367781e-04f, - 3.47318778e-04f, 3.43246495e-04f, 3.39125459e-04f, 3.34970052e-04f, 3.30801775e-04f, 3.26558719e-04f, - 3.22277893e-04f, 3.18001720e-04f, 3.13643657e-04f, 3.09254677e-04f, 3.04807328e-04f, 3.00403461e-04f, - 2.95922394e-04f, 2.91394115e-04f, 2.86859061e-04f, 2.82240998e-04f, 2.77622100e-04f, 2.72993376e-04f, - 2.68306798e-04f, 2.63604407e-04f, 2.58825298e-04f, 2.54096955e-04f, 2.49263568e-04f, 2.44458698e-04f, - 2.39553036e-04f, 2.34700765e-04f, 2.29807080e-04f, 2.24838007e-04f, 2.19880576e-04f, 2.14901783e-04f, - 2.09895136e-04f, 2.04859730e-04f, 1.99785752e-04f, 1.94756699e-04f, 1.89629933e-04f, 1.84505149e-04f, - 1.79379344e-04f, 1.74222854e-04f, 1.69062811e-04f, 1.63837116e-04f, 1.58640764e-04f, 1.53435943e-04f, - 1.48205527e-04f, 1.42916002e-04f, 1.37685538e-04f, 1.32386712e-04f, 1.27109519e-04f, 1.21759188e-04f, - 1.16494464e-04f, 1.11104096e-04f, 1.05837507e-04f, 1.00413673e-04f, 9.51224828e-05f, 8.97002750e-05f, - 8.43547969e-05f, 7.90010298e-05f, 7.35842631e-05f, 6.82236801e-05f, 6.28025851e-05f, 5.74352340e-05f, - 5.20208143e-05f, 4.66316276e-05f, 4.11998540e-05f, 3.57940416e-05f, 3.04059253e-05f, 2.50147246e-05f, - 1.95913509e-05f, 1.41939837e-05f, 8.79121075e-06f, 3.43114505e-06f, -2.01794026e-06f, -7.36418885e-06f, - -1.27630594e-05f, -1.81187612e-05f, -2.34992296e-05f, -2.88582377e-05f, -3.42611068e-05f, -3.95840867e-05f, - -4.49139978e-05f, -5.01960756e-05f, -5.55347440e-05f, -6.08432847e-05f, -6.61792468e-05f, -7.13909182e-05f, - -7.66559452e-05f, -8.19268977e-05f, -8.71628140e-05f, -9.23732336e-05f, -9.75867093e-05f, -1.02773663e-04f, - -1.07957800e-04f, -1.13116527e-04f, -1.18256210e-04f, -1.23356464e-04f, -1.28415766e-04f, -1.33506383e-04f, - -1.38558787e-04f, -1.43588690e-04f, -1.48602977e-04f, -1.53619022e-04f, -1.58574636e-04f, -1.63469116e-04f, - -1.68406584e-04f, -1.73271933e-04f, -1.78181992e-04f, -1.83003500e-04f, -1.87822434e-04f, -1.92563811e-04f, - -1.97323987e-04f, -2.02018849e-04f, -2.06716354e-04f, -2.11407354e-04f, -2.16039634e-04f, -2.20650955e-04f, - -2.25194585e-04f, -2.29771428e-04f, -2.34198673e-04f, -2.38709010e-04f, -2.43120285e-04f, -2.47525886e-04f, - -2.51897034e-04f, -2.56214617e-04f, -2.60474284e-04f, -2.64777888e-04f, -2.68998213e-04f, -2.73213272e-04f, - -2.77298579e-04f, -2.81440782e-04f, -2.85442493e-04f, -2.89526086e-04f, -2.93506309e-04f, -2.97462851e-04f, - -3.01376236e-04f, -3.05192266e-04f, -3.08983506e-04f, -3.12745275e-04f, -3.16500387e-04f, -3.20193015e-04f, - -3.23862094e-04f, -3.27445142e-04f, -3.30995027e-04f, -3.34513010e-04f, -3.37996668e-04f, -3.41383601e-04f, - -3.44751306e-04f, -3.48091886e-04f, -3.51406207e-04f, -3.54623953e-04f, -3.57754823e-04f, -3.60891922e-04f, - -3.63984968e-04f, -3.67018982e-04f, -3.69964703e-04f, -3.72973588e-04f, -3.75828235e-04f, -3.78688862e-04f, - -3.81456319e-04f, -3.84144925e-04f, -3.86865911e-04f, -3.89505290e-04f, -3.92102917e-04f, -3.94611260e-04f, - -3.97056130e-04f, -3.99511955e-04f, -4.01874150e-04f, -4.04180340e-04f, -4.06433718e-04f, -4.08624964e-04f, - -4.10815397e-04f, -4.12938200e-04f, -4.14972879e-04f, -4.16914095e-04f, -4.18862308e-04f, -4.20744284e-04f, - -4.22581340e-04f, -4.24353358e-04f, -4.26084854e-04f, -4.27729454e-04f, -4.29345356e-04f, -4.30889951e-04f, - -4.32326414e-04f, -4.33769811e-04f, -4.35145240e-04f, -4.36525464e-04f, -4.37734459e-04f, -4.38980042e-04f, - -4.40063899e-04f, -4.41176962e-04f, -4.42188855e-04f, -4.43216655e-04f, -4.44119059e-04f, -4.45007196e-04f, - -4.45784555e-04f, -4.46496861e-04f, -4.47225762e-04f, -4.47850574e-04f, -4.48381713e-04f, -4.48913676e-04f, - -4.49396920e-04f, -4.49776134e-04f, -4.50136429e-04f, -4.50364235e-04f, -4.50601432e-04f, -4.50790122e-04f, - -4.50912376e-04f, -4.50920431e-04f, -4.50917014e-04f, -4.50853859e-04f, -4.50769852e-04f, -4.50551253e-04f, - -4.50336025e-04f, -4.50005806e-04f, -4.49666788e-04f, -4.49249940e-04f, -4.48804538e-04f, -4.48256799e-04f, - -4.47659057e-04f, -4.47042228e-04f, -4.46366931e-04f, -4.45571896e-04f, -4.44761839e-04f, -4.43893828e-04f, - -4.43037133e-04f, -4.42039044e-04f, -4.40978459e-04f, -4.39857218e-04f, -4.38764474e-04f, -4.37523448e-04f, - -4.36309543e-04f, -4.34982242e-04f, -4.33652985e-04f, -4.32180019e-04f, -4.30695628e-04f, -4.29203566e-04f, - -4.27595028e-04f, -4.25950991e-04f, -4.24295734e-04f, -4.22525840e-04f, -4.20738592e-04f, -4.18889529e-04f, - -4.16969130e-04f, -4.15071943e-04f, -4.13037714e-04f, -4.10969372e-04f, -4.08861770e-04f, -4.06716648e-04f, - -4.04538109e-04f, -4.02237421e-04f, -3.99934445e-04f, -3.97569391e-04f, -3.95173141e-04f, -3.92724412e-04f, - -3.90170686e-04f, -3.87662368e-04f, -3.85002969e-04f, -3.82430599e-04f, -3.79700132e-04f, -3.76954078e-04f, - -3.74194441e-04f, -3.71301874e-04f, -3.68448275e-04f, -3.65531762e-04f, -3.62563314e-04f, -3.59534878e-04f, - -3.56456067e-04f, -3.53385083e-04f, -3.50196503e-04f, -3.47053578e-04f, -3.43809117e-04f, -3.40550373e-04f, - -3.37222190e-04f, -3.33814770e-04f, -3.30452429e-04f, -3.27022252e-04f, -3.23548998e-04f, -3.20049341e-04f, - -3.16466673e-04f, -3.12887579e-04f, -3.09224225e-04f, -3.05567282e-04f, -3.01885097e-04f, -2.98104963e-04f, - -2.94375137e-04f, -2.90539167e-04f, -2.86755477e-04f, -2.82814804e-04f, -2.78882289e-04f, -2.74946506e-04f, - -2.71013915e-04f, -2.66969297e-04f, -2.62909733e-04f, -2.58857620e-04f, -2.54745434e-04f, -2.50597356e-04f, - -2.46434558e-04f, -2.42248826e-04f, -2.38044637e-04f, -2.33799265e-04f, -2.29509695e-04f, -2.25216648e-04f, - -2.20874892e-04f, -2.16486394e-04f, -2.12133319e-04f, -2.07694626e-04f, -2.03325588e-04f, -1.98876948e-04f, - -1.94363244e-04f, -1.89842578e-04f, -1.85348686e-04f, -1.80819273e-04f, -1.76288992e-04f, -1.71687149e-04f, - -1.67069824e-04f, -1.62486983e-04f, -1.57849710e-04f, -1.53190154e-04f, -1.48471771e-04f, -1.43818764e-04f, - -1.39139875e-04f, -1.34422736e-04f, -1.29679663e-04f, -1.24929434e-04f, -1.20167360e-04f, -1.15399762e-04f, - -1.10617766e-04f, -1.05792157e-04f, -1.01051863e-04f, -9.62199475e-05f, -9.13898776e-05f, -8.65501522e-05f, - -8.16930662e-05f, -7.68436192e-05f, -7.20100759e-05f, -6.71215946e-05f, -6.22648831e-05f, -5.74032294e-05f, - -5.25396404e-05f, -4.76390344e-05f, -4.27300277e-05f, -3.78461036e-05f, -3.29682633e-05f, -2.81055383e-05f, - -2.31679660e-05f, -1.83096351e-05f, -1.33935626e-05f, -8.50161570e-06f, -3.61640946e-06f, 1.28987770e-06f, - 6.17037159e-06f, 1.10323689e-05f, 1.59247370e-05f, 2.08131611e-05f, 2.56424068e-05f, 3.05600970e-05f, - 3.53617557e-05f, 4.02091289e-05f, 4.50696551e-05f, 4.99026650e-05f, 5.47296737e-05f, 5.95563887e-05f, - 6.43653923e-05f, 6.91486878e-05f, 7.39350848e-05f, 7.86904475e-05f, 8.34486488e-05f, 8.81971254e-05f, - 9.29076934e-05f, 9.76401986e-05f, 1.02370226e-04f, 1.07054882e-04f, 1.11717599e-04f, 1.16339079e-04f, - 1.21006764e-04f, 1.25636431e-04f, 1.30233967e-04f, 1.34811155e-04f, 1.39362321e-04f, 1.43910083e-04f, - 1.48429634e-04f, 1.52944809e-04f, 1.57419068e-04f, 1.61875698e-04f, 1.66315797e-04f, 1.70734840e-04f, - 1.75103284e-04f, 1.79480968e-04f, 1.83834002e-04f, 1.88156120e-04f, 1.92408693e-04f, 1.96688625e-04f, - 2.00939142e-04f, 2.05162726e-04f, 2.09328817e-04f, 2.13466711e-04f, 2.17593554e-04f, 2.21676410e-04f, - 2.25710568e-04f, 2.29792869e-04f, 2.33788716e-04f, 2.37755772e-04f, 2.41680105e-04f, 2.45580530e-04f, - 2.49415352e-04f, 2.53268183e-04f, 2.57093088e-04f, 2.60889996e-04f, 2.64609693e-04f, 2.68352955e-04f, - 2.71988280e-04f, 2.75555064e-04f, 2.79216817e-04f, 2.82727827e-04f, 2.86292517e-04f, 2.89747512e-04f, - 2.93214250e-04f, 2.96625545e-04f, 2.99968730e-04f, 3.03293449e-04f, 3.06590612e-04f, 3.09831840e-04f, - 3.13062575e-04f, 3.16191445e-04f, 3.19335471e-04f, 3.22411537e-04f, 3.25459066e-04f, 3.28453391e-04f, - 3.31411517e-04f, 3.34326499e-04f, 3.37190815e-04f, 3.40014460e-04f, 3.42813791e-04f, 3.45478608e-04f, - 3.48228629e-04f, 3.50828923e-04f, 3.53492132e-04f, 3.56024641e-04f, 3.58486623e-04f, 3.60995126e-04f, - 3.63389655e-04f, 3.65758722e-04f, 3.68073027e-04f, 3.70382307e-04f, 3.72565817e-04f, 3.74794146e-04f, - 3.76906566e-04f, 3.78977046e-04f, 3.81033243e-04f, 3.83018776e-04f, 3.84951048e-04f, 3.86822651e-04f, - 3.88669518e-04f, 3.90461828e-04f, 3.92197836e-04f, 3.93890019e-04f, 3.95508138e-04f, 3.97139938e-04f, - 3.98616902e-04f, 4.00169586e-04f, 4.01568926e-04f, 4.02965744e-04f, 4.04287795e-04f, 4.05574737e-04f, - 4.06801856e-04f, 4.07975945e-04f, 4.09114424e-04f, 4.10207386e-04f, 4.11235835e-04f, 4.12210598e-04f, - 4.13136627e-04f, 4.13982278e-04f, 4.14809061e-04f, 4.15575763e-04f, 4.16237043e-04f, 4.16913110e-04f, - 4.17533720e-04f, 4.18067730e-04f, 4.18566536e-04f, 4.18988455e-04f, 4.19446768e-04f, 4.19796155e-04f, - 4.20100702e-04f, 4.20272853e-04f, 4.20522438e-04f, 4.20563404e-04f, 4.20655694e-04f, 4.20731371e-04f, - 4.20698690e-04f, 4.20612336e-04f, 4.20433171e-04f, 4.20281091e-04f, 4.19985028e-04f, 4.19758760e-04f, - 4.19391820e-04f, 4.19021715e-04f, 4.18585116e-04f, 4.18023912e-04f, 4.17480428e-04f, 4.16867720e-04f, - 4.16237162e-04f, 4.15503896e-04f, 4.14732659e-04f, 4.13957176e-04f, 4.13054887e-04f, 4.12147183e-04f, - 4.11153705e-04f, 4.10138203e-04f, 4.09138236e-04f, 4.07990880e-04f, 4.06818125e-04f, 4.05537577e-04f, - 4.04277724e-04f, 4.03011642e-04f, 4.01586690e-04f, 4.00160624e-04f, 3.98692538e-04f, 3.97171478e-04f, - 3.95627475e-04f, 3.93986354e-04f, 3.92315441e-04f, 3.90547121e-04f, 3.88834114e-04f, 3.87027020e-04f, - 3.85141158e-04f, 3.83241849e-04f, 3.81280173e-04f, 3.79307882e-04f, 3.77191763e-04f, 3.75121785e-04f, - 3.72969301e-04f, 3.70822826e-04f, 3.68591426e-04f, 3.66231379e-04f, 3.63938493e-04f, 3.61539684e-04f, - 3.59160670e-04f, 3.56720537e-04f, 3.54213927e-04f, 3.51650151e-04f, 3.49026158e-04f, 3.46392103e-04f, - 3.43663372e-04f, 3.40964068e-04f, 3.38257154e-04f, 3.35402415e-04f, 3.32616809e-04f, 3.29696051e-04f, - 3.26808503e-04f, 3.23783053e-04f, 3.20806192e-04f, 3.17789903e-04f, 3.14706396e-04f, 3.11559941e-04f, - 3.08406511e-04f, 3.05195809e-04f, 3.01964192e-04f, 2.98687960e-04f, 2.95369084e-04f, 2.91974192e-04f, - 2.88648746e-04f, 2.85227321e-04f, 2.81766303e-04f, 2.78286957e-04f, 2.74767131e-04f, 2.71248703e-04f, - 2.67635833e-04f, 2.64024527e-04f, 2.60356567e-04f, 2.56691048e-04f, 2.52955904e-04f, 2.49221925e-04f, - 2.45405489e-04f, 2.41608763e-04f, 2.37752563e-04f, 2.33922398e-04f, 2.29990243e-04f, 2.26113403e-04f, - 2.22145830e-04f, 2.18157839e-04f, 2.14219057e-04f, 2.10115381e-04f, 2.06130163e-04f, 2.02032042e-04f, - 1.97936221e-04f, 1.93773918e-04f, 1.89657914e-04f, 1.85452059e-04f, 1.81243664e-04f, 1.77030282e-04f, - 1.72783456e-04f, 1.68562394e-04f, 1.64220257e-04f, 1.59949695e-04f, 1.55620973e-04f, 1.51272011e-04f, - 1.46914302e-04f, 1.42528613e-04f, 1.38131478e-04f, 1.33763681e-04f, 1.29343766e-04f, 1.24907245e-04f, - 1.20398710e-04f, 1.15966755e-04f, 1.11495489e-04f, 1.06994416e-04f, 1.02451241e-04f, 9.79007069e-05f, - 9.33797551e-05f, 8.88430304e-05f, 8.42928816e-05f, 7.97175380e-05f, 7.51722254e-05f, 7.05409980e-05f, - 6.59500197e-05f, 6.13213084e-05f, 5.67861782e-05f, 5.21623990e-05f, 4.75196660e-05f, 4.28658413e-05f, - 3.82268293e-05f, 3.35957452e-05f, 2.89872248e-05f, 2.42681561e-05f, 1.96944509e-05f, 1.49960325e-05f, - 1.03434733e-05f, 5.68432384e-06f, 1.03619641e-06f, -3.59140129e-06f, -8.26771450e-06f, -1.28964086e-05f, - -1.75770870e-05f, -2.22144500e-05f, -2.68568077e-05f, -3.15112330e-05f, -3.61709251e-05f, -4.08414844e-05f, - -4.54590918e-05f, -5.00469420e-05f, -5.46748095e-05f, -5.93162820e-05f, -6.39316278e-05f, -6.85178743e-05f, - -7.30850704e-05f, -7.76460414e-05f, -8.22010575e-05f, -8.67510432e-05f, -9.13144035e-05f, -9.58949927e-05f, - -1.00442528e-04f, -1.04920471e-04f, -1.09465248e-04f, -1.13955939e-04f, -1.18427806e-04f, -1.22914450e-04f, - -1.27359917e-04f, -1.31801800e-04f, -1.36203616e-04f, -1.40631681e-04f, -1.44939093e-04f, -1.49346755e-04f, - -1.53694664e-04f, -1.58037364e-04f, -1.62361809e-04f, -1.66622703e-04f, -1.70918986e-04f, -1.75167682e-04f, - -1.79403791e-04f, -1.83582419e-04f, -1.87797506e-04f, -1.91961911e-04f, -1.96079852e-04f, -2.00226527e-04f, - -2.04354285e-04f, -2.08416513e-04f, -2.12444785e-04f, -2.16455925e-04f, -2.20491522e-04f, -2.24491187e-04f, - -2.28401103e-04f, -2.32300464e-04f, -2.36210146e-04f, -2.40051713e-04f, -2.43865307e-04f, -2.47632301e-04f, - -2.51438394e-04f, -2.55206060e-04f, -2.58885784e-04f, -2.62578071e-04f, -2.66262448e-04f, -2.69869507e-04f, - -2.73464811e-04f, -2.76997523e-04f, -2.80542156e-04f, -2.84038388e-04f, -2.87506958e-04f, -2.90929125e-04f, - -2.94266965e-04f, -2.97594146e-04f, -3.00938333e-04f, -3.04211414e-04f, -3.07511455e-04f, -3.10662269e-04f, - -3.13829448e-04f, -3.16967909e-04f, -3.20093729e-04f, -3.23172685e-04f, -3.26156208e-04f, -3.29160085e-04f, - -3.32093054e-04f, -3.35005140e-04f, -3.37850601e-04f, -3.40709817e-04f, -3.43481062e-04f, -3.46187902e-04f, - -3.48877195e-04f, -3.51560930e-04f, -3.54218553e-04f, -3.56787643e-04f, -3.59277768e-04f, -3.61797206e-04f, - -3.64242469e-04f, -3.66689336e-04f, -3.69034861e-04f, -3.71360826e-04f, -3.73599204e-04f, -3.75870762e-04f, - -3.78012654e-04f, -3.80199438e-04f, -3.82256959e-04f, -3.84358417e-04f, -3.86279997e-04f, -3.88323706e-04f, - -3.90177493e-04f, -3.92143536e-04f, -3.93944792e-04f, -3.95692497e-04f, -3.97451608e-04f, -3.99103366e-04f, - -4.00736074e-04f, -4.02276785e-04f, -4.03863139e-04f, -4.05391260e-04f, -4.06854988e-04f, -4.08188212e-04f, - -4.09572486e-04f, -4.10862997e-04f, -4.12129934e-04f, -4.13379753e-04f, -4.14443373e-04f, -4.15639278e-04f, - -4.16675669e-04f, -4.17712685e-04f, -4.18672540e-04f, -4.19560121e-04f, -4.20416507e-04f, -4.21207115e-04f, - -4.21996045e-04f, -4.22727818e-04f, -4.23412120e-04f, -4.24045299e-04f, -4.24564386e-04f, -4.24999546e-04f, - -4.25558658e-04f, -4.26013090e-04f, -4.26311433e-04f, -4.26525367e-04f, -4.26930122e-04f, -4.27191941e-04f, - -4.27344274e-04f, -4.27280699e-04f, -4.27389939e-04f, -4.27567663e-04f, -4.27583834e-04f, -4.27281206e-04f, - -4.27140206e-04f, -4.27048499e-04f, -4.26962323e-04f, -4.26539461e-04f, -4.26039047e-04f, -4.25755714e-04f, - -4.25450428e-04f, -4.24958092e-04f, -4.24297301e-04f, -4.23660367e-04f, -4.23098246e-04f, -4.22506931e-04f, - -4.21676220e-04f, -4.20857180e-04f, -4.20073509e-04f, -4.19212497e-04f, -4.18301781e-04f, -4.17262659e-04f, - -4.16120384e-04f, -4.15203924e-04f, -4.14096405e-04f, -4.12929763e-04f, -4.11636374e-04f, -4.10311849e-04f, - -4.09048192e-04f, -4.07712544e-04f, -4.06253058e-04f, -4.04791274e-04f, -4.03250811e-04f, -4.01706706e-04f, - -4.00114574e-04f, -3.98474490e-04f, -3.96772202e-04f, -3.95026809e-04f, -3.93198260e-04f, -3.91386706e-04f, - -3.89547774e-04f, -3.87606095e-04f, -3.85558829e-04f, -3.83542445e-04f, -3.81508629e-04f, -3.79420966e-04f, - -3.77253467e-04f, -3.74974123e-04f, -3.72799249e-04f, -3.70559303e-04f, -3.68193121e-04f, -3.65772662e-04f, - -3.63380724e-04f, -3.60971221e-04f, -3.58455187e-04f, -3.55762967e-04f, -3.53225518e-04f, -3.50703713e-04f, - -3.48078998e-04f, -3.45262339e-04f, -3.42436652e-04f, -3.39695574e-04f, -3.37017640e-04f, -3.34066185e-04f, - -3.31031621e-04f, -3.28156452e-04f, -3.25220124e-04f, -3.22210235e-04f, -3.19068447e-04f, -3.15862860e-04f, - -3.12833030e-04f, -3.09697125e-04f, -3.06465515e-04f, -3.03130016e-04f, -2.99915735e-04f, -2.96601321e-04f, - -2.93296024e-04f, -2.89818405e-04f, -2.86407470e-04f, -2.82972539e-04f, -2.79475006e-04f, -2.75933130e-04f, - -2.72371673e-04f, -2.68784346e-04f, -2.65183803e-04f, -2.61496288e-04f, -2.57803064e-04f, -2.54114033e-04f, - -2.50349450e-04f, -2.46619016e-04f, -2.42760684e-04f, -2.38926134e-04f, -2.35094492e-04f, -2.31238078e-04f, - -2.27230034e-04f, -2.23293238e-04f, -2.19324859e-04f, -2.15442596e-04f, -2.11372211e-04f, -2.07224354e-04f, - -2.03182071e-04f, -1.99129382e-04f, -1.95014895e-04f, -1.90770991e-04f, -1.86588551e-04f, -1.82500857e-04f, - -1.78339777e-04f, -1.73976343e-04f, -1.69667605e-04f, -1.65405643e-04f, -1.61236717e-04f, -1.56943488e-04f, - -1.52502205e-04f, -1.48089808e-04f, -1.43769616e-04f, -1.39437277e-04f, -1.34986925e-04f, -1.30496041e-04f, - -1.26073058e-04f, -1.21682567e-04f, -1.17217246e-04f, -1.12647224e-04f, -1.08145595e-04f, -1.03626669e-04f, - -9.91749149e-05f, -9.46100635e-05f, -9.00198055e-05f, -8.54087892e-05f, -8.08619813e-05f, -7.62877606e-05f, - -7.16800659e-05f, -6.70673725e-05f, -6.24552228e-05f, -5.78229250e-05f, -5.31857384e-05f, -4.85099894e-05f, - -4.38889983e-05f, -3.91993803e-05f, -3.45736653e-05f, -2.98966869e-05f, -2.52586203e-05f, -2.05939750e-05f, - -1.58040119e-05f, -1.11428997e-05f, -6.42985829e-06f, -1.77793099e-06f, 2.88776200e-06f, 7.60251022e-06f, - 1.23358727e-05f, 1.69525146e-05f, 2.16623216e-05f, 2.64475930e-05f, 3.11410738e-05f, 3.57241898e-05f, - 4.03951842e-05f, 4.51557233e-05f, 4.98683978e-05f, 5.45555795e-05f, 5.91197818e-05f, 6.38170802e-05f, - 6.86106947e-05f, 7.32636011e-05f, 7.78316099e-05f, 8.23984467e-05f, 8.71155544e-05f, 9.18336432e-05f, - 9.63899015e-05f, 1.00926952e-04f, 1.05575925e-04f, 1.10214736e-04f, 1.14809231e-04f, 1.19305273e-04f, - 1.23814644e-04f, 1.28427869e-04f, 1.32998225e-04f, 1.37465982e-04f, 1.41968309e-04f, 1.46457628e-04f, - 1.50944617e-04f, 1.55423265e-04f, 1.59866476e-04f, 1.64299709e-04f, 1.68704574e-04f, 1.73090869e-04f, - 1.77440897e-04f, 1.81785220e-04f, 1.86175987e-04f, 1.90469708e-04f, 1.94842053e-04f, 1.99070471e-04f, - 2.03339864e-04f, 2.07486483e-04f, 2.11745099e-04f, 2.15968315e-04f, 2.20231405e-04f, 2.24364719e-04f, - 2.28395902e-04f, 2.32456321e-04f, 2.36571481e-04f, 2.40736656e-04f, 2.44688327e-04f, 2.48688501e-04f, - 2.52616967e-04f, 2.56664248e-04f, 2.60628393e-04f, 2.64438381e-04f, 2.68256224e-04f, 2.72112062e-04f, - 2.75980587e-04f, 2.79804389e-04f, 2.83449617e-04f, 2.87326892e-04f, 2.90950134e-04f, 2.94639661e-04f, - 2.98092238e-04f, 3.01674812e-04f, 3.05302844e-04f, 3.08894893e-04f, 3.12412339e-04f, 3.15838048e-04f, - 3.19258390e-04f, 3.22649171e-04f, 3.25992218e-04f, 3.29324690e-04f, 3.32693229e-04f, 3.35773573e-04f, - 3.39141354e-04f, 3.42306330e-04f, 3.45460164e-04f, 3.48456346e-04f, 3.51491477e-04f, 3.54581877e-04f, - 3.57528829e-04f, 3.60536774e-04f, 3.63415532e-04f, 3.66323134e-04f, 3.69193165e-04f, 3.71864060e-04f, - 3.74643327e-04f, 3.77393654e-04f, 3.80050953e-04f, 3.82656007e-04f, 3.85212036e-04f, 3.87831113e-04f, - 3.90262180e-04f, 3.92699485e-04f, 3.95175253e-04f, 3.97537602e-04f, 3.99877034e-04f, 4.02084937e-04f, - 4.04310046e-04f, 4.06603666e-04f, 4.08778222e-04f, 4.10837320e-04f, 4.12851152e-04f, 4.14874626e-04f, - 4.16896028e-04f, 4.18688346e-04f, 4.20603419e-04f, 4.22483088e-04f, 4.24376211e-04f, 4.26041269e-04f, - 4.27648097e-04f, 4.29334952e-04f, 4.30973667e-04f, 4.32503790e-04f, 4.33949299e-04f, 4.35382184e-04f, - 4.36883779e-04f, 4.38185453e-04f, 4.39451711e-04f, 4.40710767e-04f, 4.41941182e-04f, 4.43130100e-04f, - 4.44138439e-04f, 4.45250972e-04f, 4.46332498e-04f, 4.47296281e-04f, 4.48124930e-04f, 4.48991618e-04f, - 4.49792263e-04f, 4.50544176e-04f, 4.51231662e-04f, 4.51921730e-04f, 4.52479292e-04f, 4.53111401e-04f, - 4.53602773e-04f, 4.53990582e-04f, 4.54433413e-04f, 4.54731649e-04f, 4.55053293e-04f, 4.55316133e-04f, - 4.55538753e-04f, 4.55627166e-04f, 4.55658179e-04f, 4.55692033e-04f, 4.55725124e-04f, 4.55662129e-04f, - 4.55513471e-04f, 4.55383536e-04f, 4.55135704e-04f, 4.54876893e-04f, 4.54434102e-04f, 4.54085869e-04f, - 4.53709058e-04f, 4.53269091e-04f, 4.52682375e-04f, 4.52029572e-04f, 4.51383726e-04f, 4.50700851e-04f, - 4.49925159e-04f, 4.49168514e-04f, 4.48272751e-04f, 4.47398207e-04f, 4.46374847e-04f, 4.45381078e-04f, - 4.44322759e-04f, 4.43217570e-04f, 4.42000714e-04f, 4.40804795e-04f, 4.39583076e-04f, 4.38201055e-04f, - 4.36818760e-04f, 4.35343037e-04f, 4.33881241e-04f, 4.32357327e-04f, 4.30758084e-04f, 4.29133530e-04f, - 4.27436919e-04f, 4.25682460e-04f, 4.23882910e-04f, 4.22021077e-04f, 4.20113141e-04f, 4.18205658e-04f, - 4.16220534e-04f, 4.14152653e-04f, 4.12033451e-04f, 4.09918565e-04f, 4.07689095e-04f, 4.05401336e-04f, - 4.03131268e-04f, 4.00807921e-04f, 3.98431720e-04f, 3.95909434e-04f, 3.93466139e-04f, 3.90893780e-04f, - 3.88304538e-04f, 3.85672009e-04f, 3.82987015e-04f, 3.80221340e-04f, 3.77460798e-04f, 3.74602243e-04f, - 3.71709463e-04f, 3.68782179e-04f, 3.65770657e-04f, 3.62752831e-04f, 3.59689983e-04f, 3.56600554e-04f, - 3.53410228e-04f, 3.50179131e-04f, 3.46886221e-04f, 3.43626466e-04f, 3.40256905e-04f, 3.36912501e-04f, - 3.33400530e-04f, 3.29929344e-04f, 3.26348829e-04f, 3.22787226e-04f, 3.19142460e-04f, 3.15515692e-04f, - 3.11786746e-04f, 3.08075587e-04f, 3.04245385e-04f, 3.00396238e-04f, 2.96531705e-04f, 2.92536574e-04f, - 2.88625135e-04f, 2.84680219e-04f, 2.80590700e-04f, 2.76436032e-04f, 2.72304364e-04f, 2.68186520e-04f, - 2.63956493e-04f, 2.59641931e-04f, 2.55345659e-04f, 2.51094119e-04f, 2.46766963e-04f, 2.42369371e-04f, - 2.37793247e-04f, 2.33313721e-04f, 2.28797803e-04f, 2.24338307e-04f, 2.19673062e-04f, 2.14983647e-04f, - 2.10410231e-04f, 2.05699935e-04f, 2.00972912e-04f, 1.96069487e-04f, 1.91298675e-04f, 1.86566896e-04f, - 1.81692462e-04f, 1.76732804e-04f, 1.71720694e-04f, 1.66801145e-04f, 1.61807263e-04f, 1.56702072e-04f, - 1.51671071e-04f, 1.46622257e-04f, 1.41458282e-04f, 1.36321583e-04f, 1.31081479e-04f, 1.25854407e-04f, - 1.20594126e-04f, 1.15340795e-04f, 1.10055148e-04f, 1.04702656e-04f, 9.93987347e-05f, 9.39597776e-05f, - 8.84719837e-05f, 8.30352071e-05f, 7.76151782e-05f, 7.21392897e-05f, 6.66066852e-05f, 6.09794471e-05f, - 5.54838929e-05f, 4.99007371e-05f, 4.43151865e-05f, 3.85781491e-05f, 3.28997966e-05f, 2.72762043e-05f, - 2.15809628e-05f, 1.58299548e-05f, 1.00539198e-05f, 4.30655863e-06f, -1.46500193e-06f, -7.30311317e-06f, - -1.31385737e-05f, -1.89713864e-05f, -2.47898326e-05f, -3.06272323e-05f, -3.66075277e-05f, -4.25369158e-05f, - -4.84883964e-05f, -5.44017375e-05f, -6.03401172e-05f, -6.63717105e-05f, -7.23299518e-05f, -7.83566216e-05f, - -8.43505284e-05f, -9.03764737e-05f, -9.64632322e-05f, -1.02503982e-04f, -1.08576405e-04f, -1.14659107e-04f, - -1.20727608e-04f, -1.26833627e-04f, -1.32966106e-04f, -1.39111768e-04f, -1.45262299e-04f, -1.51348373e-04f, - -1.57544580e-04f, -1.63685469e-04f, -1.69796495e-04f, -1.75950870e-04f, -1.82176730e-04f, -1.88408521e-04f, - -1.94595833e-04f, -2.00744189e-04f, -2.06966020e-04f, -2.13217571e-04f, -2.19451227e-04f, -2.25556684e-04f, - -2.31736398e-04f, -2.37988311e-04f, -2.44272936e-04f, -2.50519686e-04f, -2.56677713e-04f, -2.62907431e-04f, - -2.69104943e-04f, -2.75347024e-04f, -2.81576331e-04f, -2.87701705e-04f, -2.94002003e-04f, -3.00291596e-04f, - -3.06505255e-04f, -3.12658992e-04f, -3.18840018e-04f, -3.25027242e-04f, -3.31264148e-04f, -3.37423292e-04f, - -3.43644138e-04f, -3.49806080e-04f, -3.56088640e-04f, -3.62199165e-04f, -3.68336013e-04f, -3.74463224e-04f, - -3.80564064e-04f, -3.86782951e-04f, -3.92966068e-04f, -3.99074371e-04f, -4.05185873e-04f, -4.11243974e-04f, - -4.17325738e-04f, -4.23367477e-04f, -4.29427860e-04f, -4.35517367e-04f, -4.41609980e-04f, -4.47645147e-04f, - -4.53612143e-04f, -4.59626005e-04f, -4.65644896e-04f, -4.71602261e-04f, -4.77517479e-04f, -4.83499897e-04f, - -4.89438396e-04f, -4.95388706e-04f, -5.01283522e-04f, -5.07113177e-04f, -5.12966943e-04f, -5.18829988e-04f, - -5.24659327e-04f, -5.30497940e-04f, -5.36259569e-04f, -5.42075495e-04f, -5.47878751e-04f, -5.53540344e-04f, - -5.59259129e-04f, -5.64867650e-04f, -5.70609631e-04f, -5.76263286e-04f, -5.81928930e-04f, -5.87538391e-04f, - -5.93064190e-04f, -5.98642710e-04f, -6.04150134e-04f, -6.09670084e-04f, -6.15171638e-04f, -6.20673705e-04f, - -6.26146730e-04f, -6.31528262e-04f, -6.36865406e-04f, -6.42252487e-04f, -6.47597819e-04f, -6.52944091e-04f, - -6.58246370e-04f, -6.63524848e-04f, -6.68704814e-04f, -6.73934063e-04f, -6.79053974e-04f, -6.84245648e-04f, - -6.89343229e-04f, -6.94510814e-04f, -6.99578136e-04f, -7.04594559e-04f, -7.09555454e-04f, -7.14486311e-04f, - -7.19468194e-04f, -7.24452666e-04f, -7.29339965e-04f, -7.34174335e-04f, -7.38952068e-04f, -7.43700371e-04f, - -7.48505340e-04f, -7.53271484e-04f, -7.57936901e-04f, -7.62561347e-04f, -7.67192950e-04f, -7.71794434e-04f, - -7.76333835e-04f, -7.80799914e-04f, -7.85329587e-04f, -7.89865475e-04f, -7.94232885e-04f, -7.98611965e-04f, - -8.02941170e-04f, -8.07320253e-04f, -8.11557732e-04f, -8.15713953e-04f, -8.19920314e-04f, -8.24120755e-04f, - -8.28281722e-04f, -8.32324184e-04f, -8.36398699e-04f, -8.40374309e-04f, -8.44378305e-04f, -8.48328550e-04f, - -8.52219459e-04f, -8.56120407e-04f, -8.59964731e-04f, -8.63724680e-04f, -8.67478476e-04f, -8.71189195e-04f, - -8.74814893e-04f, -8.78461698e-04f, -8.82048262e-04f, -8.85615733e-04f, -8.89094742e-04f, -8.92567218e-04f, - -8.96068017e-04f, -8.99411229e-04f, -9.02808954e-04f, -9.06099741e-04f, -9.09353887e-04f, -9.12589122e-04f, - -9.15759752e-04f, -9.18944810e-04f, -9.21979379e-04f, -9.25104009e-04f, -9.28081698e-04f, -9.31190339e-04f, - -9.34034319e-04f, -9.36966623e-04f, -9.39790911e-04f, -9.42564530e-04f, -9.45357467e-04f, -9.48099708e-04f, - -9.50833511e-04f, -9.53454754e-04f, -9.56005375e-04f, -9.58534983e-04f, -9.61094016e-04f, -9.63595134e-04f, - -9.66029903e-04f, -9.68413758e-04f, -9.70807097e-04f, -9.73105549e-04f, -9.75287319e-04f, -9.77431930e-04f, - -9.79643937e-04f, -9.81826671e-04f, -9.83890160e-04f, -9.85949906e-04f, -9.87890243e-04f, -9.89883561e-04f, - -9.91790522e-04f, -9.93704485e-04f, -9.95454988e-04f, -9.97232774e-04f, -9.98943613e-04f, -1.00070689e-03f, - -1.00235446e-03f, -1.00394111e-03f, -1.00544107e-03f, -1.00697233e-03f, -1.00842707e-03f, -1.00981534e-03f, - -1.01122434e-03f, -1.01256921e-03f, -1.01395820e-03f, -1.01512070e-03f, -1.01631086e-03f, -1.01744196e-03f, - -1.01861956e-03f, -1.01972386e-03f, -1.02079136e-03f, -1.02170713e-03f, -1.02266765e-03f, -1.02356313e-03f, - -1.02441347e-03f, -1.02525917e-03f, -1.02599482e-03f, -1.02675136e-03f, -1.02742421e-03f, -1.02800357e-03f, - -1.02859363e-03f, -1.02917136e-03f, -1.02972814e-03f, -1.03021933e-03f, -1.03061408e-03f, -1.03095405e-03f, - -1.03126585e-03f, -1.03160347e-03f, -1.03190046e-03f, -1.03212917e-03f, -1.03231657e-03f, -1.03242218e-03f, - -1.03251789e-03f, -1.03250702e-03f, -1.03246837e-03f, -1.03243676e-03f, -1.03244691e-03f, -1.03232254e-03f, - -1.03213159e-03f, -1.03190285e-03f, -1.03160552e-03f, -1.03139379e-03f, -1.03102772e-03f, -1.03063889e-03f, - -1.03023943e-03f, -1.02983657e-03f, -1.02935075e-03f, -1.02882003e-03f, -1.02815007e-03f, -1.02755167e-03f, - -1.02694727e-03f, -1.02627897e-03f, -1.02553484e-03f, -1.02468419e-03f, -1.02388781e-03f, -1.02305055e-03f, - -1.02224154e-03f, -1.02126341e-03f, -1.02029309e-03f, -1.01921008e-03f, -1.01820921e-03f, -1.01714461e-03f, - -1.01602749e-03f, -1.01489771e-03f, -1.01368693e-03f, -1.01246900e-03f, -1.01116627e-03f, -1.00990379e-03f, - -1.00847263e-03f, -1.00709197e-03f, -1.00567713e-03f, -1.00430250e-03f, -1.00280109e-03f, -1.00124147e-03f, - -9.99642701e-04f, -9.98050879e-04f, -9.96452138e-04f, -9.94852286e-04f, -9.93083101e-04f, -9.91375852e-04f, - -9.89550457e-04f, -9.87760139e-04f, -9.85928860e-04f, -9.84048066e-04f, -9.82154969e-04f, -9.80235634e-04f, - -9.78245739e-04f, -9.76218086e-04f, -9.74193691e-04f, -9.72148760e-04f, -9.70071944e-04f, -9.67907685e-04f, - -9.65730712e-04f, -9.63558555e-04f, -9.61390663e-04f, -9.59115265e-04f, -9.56803484e-04f, -9.54457779e-04f, - -9.52108735e-04f, -9.49724959e-04f, -9.47277223e-04f, -9.44853722e-04f, -9.42419997e-04f, -9.39945438e-04f, - -9.37402017e-04f, -9.34778483e-04f, -9.32257848e-04f, -9.29643708e-04f, -9.27143084e-04f, -9.24393686e-04f, - -9.21669317e-04f, -9.18941578e-04f, -9.16200628e-04f, -9.13437501e-04f, -9.10619440e-04f, -9.07766847e-04f, - -9.04942198e-04f, -9.02118676e-04f, -8.99206475e-04f, -8.96292400e-04f, -8.93270259e-04f, -8.90365511e-04f, - -8.87404359e-04f, -8.84356511e-04f, -8.81292595e-04f, -8.78228061e-04f, -8.75142878e-04f, -8.72034512e-04f, - -8.68872947e-04f, -8.65676040e-04f, -8.62539123e-04f, -8.59381263e-04f, -8.56193935e-04f, -8.52900515e-04f, - -8.49616254e-04f, -8.46331406e-04f, -8.43068798e-04f, -8.39754236e-04f, -8.36403430e-04f, -8.32997431e-04f, - -8.29614520e-04f, -8.26177052e-04f, -8.22732863e-04f, -8.19388192e-04f, -8.15978291e-04f, -8.12481072e-04f, - -8.08946295e-04f, -8.05450815e-04f, -8.01993270e-04f, -7.98505010e-04f, -7.94957785e-04f, -7.91347738e-04f, - -7.87714167e-04f, -7.84044220e-04f, -7.80374635e-04f, -7.76759263e-04f, -7.73099670e-04f, -7.69551660e-04f, - -7.65903130e-04f, -7.62286082e-04f, -7.58527714e-04f, -7.54811486e-04f, -7.51078532e-04f, -7.47331525e-04f, - -7.43553919e-04f, -7.39741320e-04f, -7.36000039e-04f, -7.32170040e-04f, -7.28417328e-04f, -7.24608696e-04f, - -7.20833640e-04f, -7.16959709e-04f, -7.13106686e-04f, -7.09265819e-04f, -7.05448425e-04f, -7.01613748e-04f, - -6.97716381e-04f, -6.93784658e-04f, -6.89920641e-04f, -6.86056743e-04f, -6.82102885e-04f, -6.78139301e-04f, - -6.74286774e-04f, -6.70329068e-04f, -6.66420807e-04f, -6.62437180e-04f, -6.58512946e-04f, -6.54592492e-04f, - -6.50574690e-04f, -6.46613197e-04f, -6.42610054e-04f, -6.38673196e-04f, -6.34731872e-04f, -6.30738912e-04f, - -6.26710367e-04f, -6.22723105e-04f, -6.18721104e-04f, -6.14675773e-04f, -6.10710873e-04f, -6.06668115e-04f, - -6.02720638e-04f, -5.98692339e-04f, -5.94666643e-04f, -5.90657794e-04f, -5.86694839e-04f, -5.82597027e-04f, - -5.78597686e-04f, -5.74505959e-04f, -5.70561723e-04f, -5.66522869e-04f, -5.62500498e-04f, -5.58473872e-04f, - -5.54470803e-04f, -5.50450538e-04f, -5.46392245e-04f, -5.42439602e-04f, -5.38440705e-04f, -5.34430603e-04f, - -5.30372840e-04f, -5.26281729e-04f, -5.22298388e-04f, -5.18307610e-04f, -5.14316466e-04f, -5.10325583e-04f, - -5.06333664e-04f, -5.02290438e-04f, -4.98346139e-04f, -4.94333596e-04f, -4.90339178e-04f, -4.86401561e-04f, - -4.82473258e-04f, -4.78521741e-04f, -4.74461381e-04f, -4.70465623e-04f, -4.66484353e-04f, -4.62627814e-04f, - -4.58692844e-04f, -4.54774990e-04f, -4.50796896e-04f, -4.46863103e-04f, -4.42952721e-04f, -4.39018676e-04f, - -4.35157895e-04f, -4.31279000e-04f, -4.27374640e-04f, -4.23507463e-04f, -4.19666300e-04f, -4.15784159e-04f, - -4.11908116e-04f, -4.08042217e-04f, -4.04172564e-04f, -4.00377806e-04f, -3.96571973e-04f, -3.92712401e-04f, - -3.88879342e-04f, -3.85089612e-04f, -3.81306365e-04f, -3.77585679e-04f, -3.73803416e-04f, -3.70109886e-04f, - -3.66329658e-04f, -3.62588818e-04f, -3.58832558e-04f, -3.55114535e-04f, -3.51346321e-04f, -3.47668614e-04f, - -3.44043182e-04f, -3.40354498e-04f, -3.36737526e-04f, -3.33041920e-04f, -3.29471899e-04f, -3.25866983e-04f, - -3.22277655e-04f, -3.18632081e-04f, -3.14998814e-04f, -3.11408228e-04f, -3.07823628e-04f, -3.04313143e-04f, - -3.00825747e-04f, -2.97342084e-04f, -2.93831953e-04f, -2.90382841e-04f, -2.86862870e-04f, -2.83384067e-04f, - -2.79891743e-04f, -2.76430368e-04f, -2.73044472e-04f, -2.69690945e-04f, -2.66287404e-04f, -2.62897219e-04f, - -2.59525276e-04f, -2.56166856e-04f, -2.52882682e-04f, -2.49535435e-04f, -2.46242445e-04f, -2.42915941e-04f, - -2.39605457e-04f, -2.36359794e-04f, -2.33163640e-04f, -2.29971578e-04f, -2.26774571e-04f, -2.23550823e-04f, - -2.20363802e-04f, -2.17220630e-04f, -2.14064369e-04f, -2.10924402e-04f, -2.07813076e-04f, -2.04680727e-04f, - -2.01565460e-04f, -1.98516005e-04f, -1.95459873e-04f, -1.92431520e-04f, -1.89427340e-04f, -1.86417039e-04f, - -1.83513232e-04f, -1.80525176e-04f, -1.77557406e-04f, -1.74588452e-04f, -1.71703913e-04f, -1.68752368e-04f, - -1.65848401e-04f, -1.62963775e-04f, -1.60131525e-04f, -1.57315523e-04f, -1.54517276e-04f, -1.51741705e-04f, - -1.48988609e-04f, -1.46251763e-04f, -1.43471662e-04f, -1.40741045e-04f, -1.38035099e-04f, -1.35380571e-04f, - -1.32643725e-04f, -1.29972694e-04f, -1.27315616e-04f, -1.24686160e-04f, -1.22152785e-04f, -1.19563047e-04f, - -1.17032799e-04f, -1.14465132e-04f, -1.11930499e-04f, -1.09435231e-04f, -1.06960573e-04f, -1.04467280e-04f, - -1.02011810e-04f, -9.96178862e-05f, -9.72008399e-05f, -9.47464392e-05f, -9.23772262e-05f, -8.99947201e-05f, - -8.76687074e-05f, -8.53645763e-05f, -8.30666484e-05f, -8.07897744e-05f, -7.84591086e-05f, -7.62036704e-05f, - -7.39878565e-05f, -7.18253330e-05f, -6.96297862e-05f, -6.74141148e-05f, -6.52269514e-05f, -6.31060844e-05f, - -6.09881908e-05f, -5.89098228e-05f, -5.67900586e-05f, -5.47384014e-05f, -5.26637888e-05f, -5.06729787e-05f, - -4.86293875e-05f, -4.66876563e-05f, -4.47122597e-05f, -4.27726264e-05f, -4.08140078e-05f, -3.88032209e-05f, - -3.69062317e-05f, -3.51099796e-05f, -3.32204976e-05f, -3.13733117e-05f, -2.95294225e-05f, -2.77278195e-05f, - -2.59901373e-05f, -2.41669429e-05f, -2.23737407e-05f, -2.06663288e-05f, -1.89636461e-05f, -1.72772595e-05f, - -1.54989863e-05f, -1.38314258e-05f, -1.22324768e-05f, -1.06120390e-05f, -9.03483584e-06f, -7.38321292e-06f, - -5.81681561e-06f, -4.24454968e-06f, -2.65691713e-06f, -1.17131746e-06f, 3.32073336e-07f, 1.77853297e-06f, - 3.21995574e-06f, 4.72653744e-06f, 6.20358041e-06f, 7.63566072e-06f, 9.04825873e-06f, 1.03705367e-05f, - 1.17326998e-05f, 1.30139615e-05f, 1.44780969e-05f, 1.58527163e-05f, 1.71982560e-05f, 1.84085001e-05f, - 1.95600270e-05f, 2.07860197e-05f, 2.20449917e-05f, 2.33549226e-05f, 2.45871574e-05f, 2.57001151e-05f, - 2.68787800e-05f, 2.82291272e-05f, 2.94858619e-05f, 3.04989733e-05f, 3.14210010e-05f, 3.24184197e-05f, - 3.33700194e-05f, 3.45277297e-05f, 3.58175647e-05f, 3.69912816e-05f, 3.78588667e-05f, 3.87383944e-05f, - 3.96047531e-05f, 4.04994301e-05f, 4.15116613e-05f, 4.25574369e-05f, 4.36102243e-05f, 4.46024574e-05f, - 4.54060454e-05f, 4.60388154e-05f, 4.68574318e-05f, 4.77304133e-05f, 4.85983924e-05f, 4.94714308e-05f, - 5.03103656e-05f, 5.11307565e-05f, 5.18662370e-05f, 5.27225353e-05f, 5.34135111e-05f, 5.40309477e-05f, - 5.47750518e-05f, 5.55303724e-05f, 5.61956417e-05f, 5.68888435e-05f, 5.75229605e-05f, 5.81081739e-05f, - 5.86693729e-05f, 5.93751567e-05f, 5.99944911e-05f, 6.07119052e-05f, 6.12789450e-05f, 6.17590503e-05f, - 6.22969265e-05f, 6.28434954e-05f, 6.34136220e-05f, 6.39161242e-05f, 6.44186216e-05f, 6.49328073e-05f, - 6.53758953e-05f, 6.57079891e-05f, 6.62919839e-05f, 6.67345458e-05f, 6.71388906e-05f, 6.75505599e-05f, - 6.80579048e-05f, 6.82998761e-05f, 6.87496163e-05f, 6.91336350e-05f, 6.94691461e-05f, 6.97268724e-05f, - 7.00473916e-05f, 7.03934823e-05f, 7.07962794e-05f, 7.11193276e-05f, 7.14052898e-05f, 7.16513773e-05f, - 7.18986438e-05f, 7.22196808e-05f, 7.24247049e-05f, 7.27732354e-05f, 7.29482457e-05f, 7.31362233e-05f, - 7.32973729e-05f, 7.35069932e-05f, 7.36912344e-05f, 7.39448518e-05f, 7.41420121e-05f, 7.42329068e-05f, - 7.43003022e-05f, 7.45102559e-05f, 7.46093843e-05f, 7.48218559e-05f, 7.49020077e-05f, 7.50154476e-05f, - 7.50413364e-05f, 7.50822547e-05f, 7.52171284e-05f, 7.52636461e-05f, 7.54053543e-05f, 7.54085886e-05f, - 7.54009775e-05f, 7.54143907e-05f, 7.53873429e-05f, 7.53850543e-05f, 7.54922092e-05f, 7.55995016e-05f, - 7.55522158e-05f, 7.55292807e-05f, 7.54978740e-05f, 7.54443942e-05f, 7.53068800e-05f, 7.52657057e-05f, - 7.52576086e-05f, 7.51967448e-05f, 7.51353938e-05f, 7.50836562e-05f, 7.50387778e-05f, 7.49679116e-05f, - 7.47824603e-05f, 7.47206018e-05f, 7.46841638e-05f, 7.45224791e-05f, 7.44431169e-05f, 7.42998605e-05f, - 7.41585021e-05f, 7.37876143e-05f, 7.37139023e-05f, 7.36533917e-05f, 7.34806783e-05f, 7.32599517e-05f, - 7.31020435e-05f, 7.30540415e-05f, 7.28774364e-05f, 7.27377573e-05f, 7.25479862e-05f, 7.22998403e-05f, - 7.20310341e-05f, 7.17013247e-05f, 7.15127589e-05f, 7.13959238e-05f, 7.12978543e-05f, 7.11514073e-05f, - 7.09247913e-05f, 7.05579588e-05f, 7.01697931e-05f, 6.99455556e-05f, 6.98119239e-05f, 6.95790834e-05f, - 6.93501044e-05f, 6.90738857e-05f, 6.87241922e-05f, 6.84160542e-05f, 6.82001653e-05f, 6.78681746e-05f, - 6.75755878e-05f, 6.73342804e-05f, 6.71663509e-05f, 6.69634068e-05f, 6.66013974e-05f, 6.62014739e-05f, - 6.58781079e-05f, 6.56092625e-05f, 6.53223930e-05f, 6.49486779e-05f, 6.46563970e-05f, 6.44873614e-05f, - 6.40573320e-05f, 6.36550639e-05f, 6.32292092e-05f, 6.28567633e-05f, 6.25497073e-05f, 6.24023454e-05f, - 6.21270759e-05f, 6.18643832e-05f, 6.14455527e-05f, 6.11121051e-05f, 6.05979018e-05f, 6.03451300e-05f, - 6.00376627e-05f, 5.97121392e-05f, 5.93533514e-05f, 5.89506842e-05f, 5.85842456e-05f, 5.81786085e-05f, - 5.79224629e-05f, 5.76095338e-05f, 5.73299250e-05f, 5.68573167e-05f, 5.64772357e-05f, 5.60298858e-05f, - 5.57467208e-05f, 5.53885551e-05f, 5.49993271e-05f, 5.45730807e-05f, 5.42183295e-05f, 5.38845879e-05f, - 5.34365104e-05f, 5.30620247e-05f, 5.27161203e-05f, 5.23503015e-05f, 5.19442911e-05f, 5.16794954e-05f, - 5.11928397e-05f, 5.08283593e-05f, 5.05154854e-05f, 5.01225475e-05f, 4.96898199e-05f, 4.92775106e-05f, - 4.89751623e-05f, 4.85555965e-05f, 4.82366286e-05f, 4.78851976e-05f, 4.74232796e-05f, 4.69776567e-05f, - 4.66230847e-05f, 4.62754914e-05f, 4.59451714e-05f, 4.56264568e-05f, 4.51650641e-05f, 4.47815729e-05f, - 4.44287010e-05f, 4.41110181e-05f, 4.36998678e-05f, 4.33286089e-05f, 4.29268908e-05f, 4.26010769e-05f, - 4.21892917e-05f, 4.18695208e-05f, 4.13676341e-05f, 4.10333453e-05f, 4.06225740e-05f, 4.02736427e-05f, - 3.99131026e-05f, 3.96319814e-05f, 3.92214134e-05f, 3.88561466e-05f, 3.84526801e-05f, 3.80296895e-05f, - 3.76371759e-05f, 3.73273486e-05f, 3.71325659e-05f, 3.67589339e-05f, 3.63923164e-05f, 3.59043977e-05f, - 3.55551425e-05f, 3.51575854e-05f, 3.49120149e-05f, 3.44886768e-05f, 3.40524913e-05f, 3.35867844e-05f, - 3.33540526e-05f, 3.33217373e-05f, 3.29840131e-05f, 3.24284753e-05f, 3.19296190e-05f, 3.14802228e-05f, - 3.11003895e-05f, 3.07370383e-05f, 3.04506474e-05f, 3.01609857e-05f, 2.99597965e-05f, 2.97862243e-05f, - 2.95269130e-05f, 2.91621886e-05f, 2.87464596e-05f, 2.84169585e-05f, 2.80231572e-05f, 2.75575506e-05f, - 2.71616686e-05f, 2.68804291e-05f, 2.66165204e-05f, 2.62562763e-05f, 2.59199006e-05f, 2.55937658e-05f, - 2.52798580e-05f, 2.50157922e-05f, 2.47906056e-05f, 2.45674744e-05f, 2.42772114e-05f, 2.38572032e-05f, - 2.34956464e-05f, 2.32465073e-05f, 2.30026392e-05f, 2.26530262e-05f, 2.23006463e-05f, 2.21318285e-05f, - 2.19244705e-05f, 2.16701471e-05f, 2.12738777e-05f, 2.11386151e-05f, 2.07886291e-05f, 2.03616291e-05f, - 1.99655351e-05f, 1.95689952e-05f, 1.93975966e-05f, 1.91813856e-05f, 1.89041452e-05f, 1.87778489e-05f, - 1.85550311e-05f, 1.85103582e-05f, 1.81344405e-05f, 1.76033714e-05f, 1.73480366e-05f, 1.73606854e-05f, - 1.72006964e-05f, 1.66636878e-05f, 1.60731933e-05f, 1.59147484e-05f, 1.58727158e-05f, 1.57069071e-05f, - 1.52458181e-05f, 1.52419678e-05f, 1.51361191e-05f, 1.50485136e-05f, 1.49258267e-05f, 1.44384037e-05f, - 1.40525290e-05f, 1.37245875e-05f, 1.35140167e-05f, 1.32425782e-05f, 1.32811169e-05f, 1.30575803e-05f, - 1.28310915e-05f, 1.25711695e-05f, 1.24115258e-05f, 1.21968267e-05f, 1.17210810e-05f, 1.13665213e-05f, - 1.14684513e-05f, 1.13343630e-05f, 1.10113592e-05f, 1.06299205e-05f, 1.05282634e-05f, 1.06373167e-05f, - 1.06262595e-05f, 9.92957654e-06f, 9.55345952e-06f, 9.46359844e-06f, 9.78320190e-06f, 9.67042058e-06f, - 9.37608613e-06f, 8.97360056e-06f, 8.65449857e-06f, 8.37178414e-06f, 8.30294762e-06f, 8.56786947e-06f, - 8.56892496e-06f, 8.07783372e-06f, 7.75308281e-06f, 7.63395725e-06f, 7.60071472e-06f, 7.28442141e-06f, - 6.92347013e-06f, 6.72629068e-06f, 6.88013404e-06f, 6.97314981e-06f, 6.98250280e-06f, 6.62574805e-06f, - 6.74237686e-06f, 6.62502698e-06f, 6.25642497e-06f, 5.97997608e-06f, 5.46622191e-06f, 5.41935460e-06f, - 5.51352526e-06f, 5.36537377e-06f, 6.12537398e-06f, 6.00084787e-06f, 5.40353914e-06f, 4.88719027e-06f, - 4.51651771e-06f, 4.32467158e-06f, 4.55473573e-06f, 4.47158263e-06f, 4.13234846e-06f, 4.11694776e-06f, - 4.13994507e-06f, 3.41047878e-06f, 7.26971529e-07f, 3.45010870e-06f, 8.07478012e-06f, 6.33517143e-05f, + 0.00000000e+00f, 1.55021703e-05f, 1.46054865e-05f, 2.07057160e-05f, 2.91335519e-05f, 4.00091078e-05f, + 5.33544450e-05f, 7.03618468e-05f, 9.10821639e-05f, 1.16484613e-04f, 1.47165999e-04f, 1.84168304e-04f, + 2.28429617e-04f, 2.80913884e-04f, 3.42940399e-04f, 4.15773039e-04f, 5.01023255e-04f, 6.00234953e-04f, + 7.15133271e-04f, 8.47838855e-04f, 1.00032516e-03f, 1.17508881e-03f, 1.37452550e-03f, 1.60147614e-03f, + 1.85886458e-03f, 2.14985024e-03f, 2.47783071e-03f, 2.84666764e-03f, 3.26016878e-03f, 3.72252797e-03f, + 4.23825900e-03f, 4.81207874e-03f, 5.44904143e-03f, 6.15447208e-03f, 6.93399929e-03f, 7.79337059e-03f, + 8.73903392e-03f, 9.77729117e-03f, 1.09149561e-02f, 1.21591316e-02f, 1.35171164e-02f, 1.49965439e-02f, + 1.66053136e-02f, 1.83515384e-02f, 2.02435362e-02f, 2.22899141e-02f, 2.44995340e-02f, 2.68813362e-02f, + 2.94443254e-02f, 3.21979928e-02f, 3.51514690e-02f, 3.83143719e-02f, 4.16960560e-02f, 4.53060504e-02f, + 4.91538115e-02f, 5.32486197e-02f, 5.75998650e-02f, 6.22164253e-02f, 6.71072811e-02f, 7.22809789e-02f, + 7.77457552e-02f, 8.35095233e-02f, 8.95796944e-02f, 9.59631768e-02f, 1.02666457e-01f, 1.09695215e-01f, + 1.17054591e-01f, 1.24748885e-01f, 1.32781656e-01f, 1.41155521e-01f, 1.49872243e-01f, 1.58932534e-01f, + 1.68335961e-01f, 1.78081143e-01f, 1.88165339e-01f, 1.98584621e-01f, 2.09333789e-01f, 2.20406193e-01f, + 2.31793899e-01f, 2.43487398e-01f, 2.55475740e-01f, 2.67746404e-01f, 2.80285305e-01f, 2.93076743e-01f, + 3.06103423e-01f, 3.19346351e-01f, 3.32784916e-01f, 3.46396772e-01f, 3.60158039e-01f, 3.74043042e-01f, + 3.88024564e-01f, 4.02073759e-01f, 4.16160177e-01f, 4.30251886e-01f, 4.44315429e-01f, 4.58315954e-01f, + 4.72217175e-01f, 4.85981675e-01f, 4.99570709e-01f, 5.12944586e-01f, 5.26062401e-01f, 5.38882630e-01f, + 5.51362766e-01f, 5.63459860e-01f, 5.75130384e-01f, 5.86330458e-01f, 5.97016050e-01f, 6.07143161e-01f, + 6.16667840e-01f, 6.25546499e-01f, 6.33735979e-01f, 6.41193959e-01f, 6.47878856e-01f, 6.53750084e-01f, + 6.58768549e-01f, 6.62896349e-01f, 6.66097381e-01f, 6.68337353e-01f, 6.69583869e-01f, 6.69807061e-01f, + 6.68979117e-01f, 6.67075139e-01f, 6.64072812e-01f, 6.59952827e-01f, 6.54699116e-01f, 6.48298688e-01f, + 6.40742160e-01f, 6.32023668e-01f, 6.22141039e-01f, 6.11095903e-01f, 5.98893921e-01f, 5.85544600e-01f, + 5.71061707e-01f, 5.55463040e-01f, 5.38770639e-01f, 5.21010762e-01f, 5.02213839e-01f, 4.82414572e-01f, + 4.61651859e-01f, 4.39968628e-01f, 4.17412000e-01f, 3.94032951e-01f, 3.69886464e-01f, 3.45031084e-01f, + 3.19529091e-01f, 2.93446187e-01f, 2.66851164e-01f, 2.39815999e-01f, 2.12415399e-01f, 1.84726660e-01f, + 1.56829293e-01f, 1.28804933e-01f, 1.00736965e-01f, 7.27100355e-02f, 4.48100810e-02f, 1.71237415e-02f, + -1.02620228e-02f, -3.72599591e-02f, -6.37832871e-02f, -8.97457733e-02f, -1.15062201e-01f, -1.39648782e-01f, + -1.63423488e-01f, -1.86306368e-01f, -2.08220103e-01f, -2.29090072e-01f, -2.48845046e-01f, -2.67417270e-01f, + -2.84742946e-01f, -3.00762597e-01f, -3.15421127e-01f, -3.28668542e-01f, -3.40459849e-01f, -3.50755400e-01f, + -3.59521402e-01f, -3.66729768e-01f, -3.72358475e-01f, -3.76391839e-01f, -3.78820421e-01f, -3.79641287e-01f, + -3.78858203e-01f, -3.76481336e-01f, -3.72527677e-01f, -3.67020780e-01f, -3.59990760e-01f, -3.51474372e-01f, + -3.41514630e-01f, -3.30160971e-01f, -3.17468898e-01f, -3.03499788e-01f, -2.88320749e-01f, -2.72004315e-01f, + -2.54628056e-01f, -2.36274454e-01f, -2.17030464e-01f, -1.96986952e-01f, -1.76238733e-01f, -1.54883647e-01f, + -1.33022496e-01f, -1.10758449e-01f, -8.81964466e-02f, -6.54430504e-02f, -4.26055475e-02f, -1.97916415e-02f, + 2.89108184e-03f, 2.53355868e-02f, 4.74362201e-02f, 6.90887518e-02f, 9.01914308e-02f, 1.10644978e-01f, + 1.30353494e-01f, 1.49224772e-01f, 1.67170735e-01f, 1.84107975e-01f, 1.99958067e-01f, 2.14648181e-01f, + 2.28111323e-01f, 2.40286622e-01f, 2.51119890e-01f, 2.60563701e-01f, 2.68577740e-01f, 2.75129027e-01f, + 2.80192144e-01f, 2.83749177e-01f, 2.85790223e-01f, 2.86312986e-01f, 2.85323221e-01f, 2.82834421e-01f, + 2.78867915e-01f, 2.73452721e-01f, 2.66625431e-01f, 2.58429983e-01f, 2.48917457e-01f, 2.38145826e-01f, + 2.26179680e-01f, 2.13089734e-01f, 1.98952740e-01f, 1.83850758e-01f, 1.67870897e-01f, 1.51104879e-01f, + 1.33648388e-01f, 1.15600665e-01f, 9.70639763e-02f, 7.81429119e-02f, 5.89439889e-02f, 3.95749746e-02f, + 2.01442353e-02f, 7.60241152e-04f, -1.84690990e-02f, -3.74370397e-02f, -5.60385970e-02f, -7.41711039e-02f, + -9.17348686e-02f, -1.08633632e-01f, -1.24775254e-01f, -1.40071993e-01f, -1.54441372e-01f, -1.67806284e-01f, + -1.80095654e-01f, -1.91244732e-01f, -2.01195605e-01f, -2.09897310e-01f, -2.17306320e-01f, -2.23386736e-01f, + -2.28110407e-01f, -2.31457193e-01f, -2.33415044e-01f, -2.33980051e-01f, -2.33156463e-01f, -2.30956673e-01f, + -2.27401097e-01f, -2.22518148e-01f, -2.16343899e-01f, -2.08921985e-01f, -2.00303365e-01f, -1.90545790e-01f, + -1.79713804e-01f, -1.67877977e-01f, -1.55114789e-01f, -1.41505907e-01f, -1.27137921e-01f, -1.12101628e-01f, + -9.64915640e-02f, -8.04054232e-02f, -6.39434707e-02f, -4.72078814e-02f, -3.03021635e-02f, -1.33305082e-02f, + 3.60284977e-03f, 2.03942507e-02f, 3.69413014e-02f, 5.31433810e-02f, 6.89024656e-02f, 8.41234679e-02f, + 9.87150268e-02f, 1.12589969e-01f, 1.25665865e-01f, 1.37865538e-01f, 1.49117506e-01f, 1.59356490e-01f, + 1.68523664e-01f, 1.76567229e-01f, 1.83442499e-01f, 1.89112308e-01f, 1.93547212e-01f, 1.96725586e-01f, + 1.98633878e-01f, 1.99266486e-01f, 1.98625999e-01f, 1.96723008e-01f, 1.93576075e-01f, 1.89211557e-01f, + 1.83663562e-01f, 1.76973516e-01f, 1.69190033e-01f, 1.60368490e-01f, 1.50570805e-01f, 1.39864815e-01f, + 1.28324021e-01f, 1.16026978e-01f, 1.03056879e-01f, 8.95008829e-02f, 7.54496798e-02f, 6.09968238e-02f, + 4.62380664e-02f, 3.12708901e-02f, 1.61936956e-02f, 1.10531988e-03f, -1.38957653e-02f, -2.87119784e-02f, + -4.32472742e-02f, -5.74078385e-02f, -7.11026311e-02f, -8.42439713e-02f, -9.67481917e-02f, -1.08536049e-01f, + -1.19533350e-01f, -1.29671345e-01f, -1.38887238e-01f, -1.47124498e-01f, -1.54333373e-01f, -1.60470968e-01f, + -1.65501755e-01f, -1.69397631e-01f, -1.72138140e-01f, -1.73710602e-01f, -1.74110159e-01f, -1.73339798e-01f, + -1.71410274e-01f, -1.68340111e-01f, -1.64155335e-01f, -1.58889414e-01f, -1.52582850e-01f, -1.45283122e-01f, + -1.37044042e-01f, -1.27925722e-01f, -1.17993860e-01f, -1.07319421e-01f, -9.59781808e-02f, -8.40500777e-02f, + -7.16188049e-02f, -5.87710561e-02f, -4.55961475e-02f, -3.21851919e-02f, -1.86306406e-02f, -5.02554942e-03f, + 8.53698384e-03f, 2.19645467e-02f, 3.51659468e-02f, 4.80518693e-02f, 6.05355056e-02f, 7.25330700e-02f, + 8.39645094e-02f, 9.47537898e-02f, 1.04829753e-01f, 1.14126254e-01f, 1.22582788e-01f, 1.30144907e-01f, + 1.36764459e-01f, 1.42400029e-01f, 1.47017076e-01f, 1.50588312e-01f, 1.53093700e-01f, 1.54520736e-01f, + 1.54864367e-01f, 1.54127119e-01f, 1.52318991e-01f, 1.49457408e-01f, 1.45567062e-01f, 1.40679709e-01f, + 1.34833933e-01f, 1.28074855e-01f, 1.20453893e-01f, 1.12028129e-01f, 1.02860307e-01f, 9.30178765e-02f, + 8.25730032e-02f, 7.16016450e-02f, 6.01833134e-02f, 4.84002546e-02f, 3.63370724e-02f, 2.40800037e-02f, + 1.17163168e-02f, -6.66217400e-04f, -1.29801121e-02f, -2.51385315e-02f, -3.70562030e-02f, -4.86497748e-02f, + -5.98384928e-02f, -7.05447859e-02f, -8.06947592e-02f, -9.02187441e-02f, -9.90517313e-02f, -1.07133911e-01f, + -1.14410951e-01f, -1.20834483e-01f, -1.26362422e-01f, -1.30959116e-01f, -1.34595787e-01f, -1.37250547e-01f, + -1.38908600e-01f, -1.39562374e-01f, -1.39211442e-01f, -1.37862602e-01f, -1.35529795e-01f, -1.32233909e-01f, + -1.28002721e-01f, -1.22870611e-01f, -1.16878278e-01f, -1.10072477e-01f, -1.02505698e-01f, -9.42356124e-02f, + -8.53248753e-02f, -7.58404912e-02f, -6.58532924e-02f, -5.54376360e-02f, -4.46705953e-02f, -3.36315414e-02f, + -2.24015972e-02f, -1.10628991e-02f, 3.01894735e-04f, 1.16101918e-02f, 2.27801642e-02f, 3.37311642e-02f, + 4.43845430e-02f, 5.46640016e-02f, 6.44962637e-02f, 7.38115400e-02f, 8.25440784e-02f, 9.06325572e-02f, + 9.80206066e-02f, 1.04657146e-01f, 1.10496723e-01f, 1.15499920e-01f, 1.19633523e-01f, 1.22870824e-01f, + 1.25191729e-01f, 1.26582959e-01f, 1.27038061e-01f, 1.26557494e-01f, 1.25148528e-01f, 1.22825305e-01f, + 1.19608512e-01f, 1.15525479e-01f, 1.10609643e-01f, 1.04900592e-01f, 9.84435537e-02f, 9.12890948e-02f, + 8.34927732e-02f, 7.51146973e-02f, 6.62190194e-02f, 5.68735547e-02f, 4.71491262e-02f, 3.71191855e-02f, + 2.68591932e-02f, 1.64459573e-02f, 5.95731808e-03f, -4.52874940e-03f, -1.49344723e-02f, -2.51829130e-02f, + -3.51986373e-02f, -4.49081427e-02f, -5.42404654e-02f, -6.31276969e-02f, -7.15054163e-02f, -7.93132713e-02f, + -8.64953327e-02f, -9.30005042e-02f, -9.87829011e-02f, -1.03802223e-01f, -1.08023943e-01f, -1.11419636e-01f, + -1.13967111e-01f, -1.15650603e-01f, -1.16460855e-01f, -1.16395152e-01f, -1.15457368e-01f, -1.13657871e-01f, + -1.11013433e-01f, -1.07547117e-01f, -1.03288073e-01f, -9.82712708e-02f, -9.25372646e-02f, -8.61318657e-02f, + -7.91057486e-02f, -7.15141053e-02f, -6.34161588e-02f, -5.48747791e-02f, -4.59559696e-02f, -3.67282941e-02f, + -2.72624874e-02f, -1.76307914e-02f, -7.90648674e-03f, 1.83670340e-03f, 1.15251424e-02f, 2.10858716e-02f, + 3.04471304e-02f, 3.95388944e-02f, 4.82933904e-02f, 5.66456655e-02f, 6.45340054e-02f, 7.19003487e-02f, + 7.86908695e-02f, 8.48562395e-02f, 9.03519908e-02f, 9.51389501e-02f, 9.91834077e-02f, 1.02457361e-01f, + 1.04938834e-01f, 1.06611872e-01f, 1.07466724e-01f, 1.07499917e-01f, 1.06714213e-01f, 1.05118588e-01f, + 1.02728167e-01f, 9.95640680e-02f, 9.56532488e-02f, 9.10282406e-02f, 8.57269309e-02f, 7.97922261e-02f, + 7.32717395e-02f, 6.62174249e-02f, 5.86850536e-02f, 5.07339959e-02f, 4.24265058e-02f, 3.38274345e-02f, + 2.50036502e-02f, 1.60234844e-02f, 6.95628026e-03f, -2.12820655e-03f, -1.11602438e-02f, -2.00708281e-02f, + -2.87920337e-02f, -3.72576320e-02f, -4.54035426e-02f, -5.31684173e-02f, -6.04938939e-02f, -6.73253212e-02f, + -7.36119310e-02f, -7.93072981e-02f, -8.43697556e-02f, -8.87625537e-02f, -9.24542939e-02f, -9.54189981e-02f, + -9.76364402e-02f, -9.90921435e-02f, -9.97776003e-02f, -9.96902366e-02f, -9.88334463e-02f, -9.72165780e-02f, + -9.48547668e-02f, -9.17688999e-02f, -8.79853312e-02f, -8.35357688e-02f, -7.84569594e-02f, -7.27903677e-02f, + -6.65818940e-02f, -5.98814932e-02f, -5.27427333e-02f, -4.52224733e-02f, -3.73802459e-02f, -2.92780037e-02f, + -2.09794209e-02f, -1.25495498e-02f, -4.05425988e-03f, 4.44034349e-03f, 1.28682571e-02f, 2.11643361e-02f, + 2.92645357e-02f, 3.71066200e-02f, 4.46305203e-02f, 5.17788267e-02f, 5.84972389e-02f, 6.47349496e-02f, + 7.04450836e-02f, 7.55849928e-02f, 8.01165748e-02f, 8.40066506e-02f, 8.72270848e-02f, 8.97550618e-02f, + 9.15732179e-02f, 9.26698315e-02f, 9.30387881e-02f, 9.26796720e-02f, 9.15978025e-02f, 8.98040443e-02f, + 8.73148489e-02f, 8.41520461e-02f, 8.03426093e-02f, 7.59185468e-02f, 7.09165136e-02f, 6.53776255e-02f, + 5.93470480e-02f, 5.28736293e-02f, 4.60095655e-02f, 3.88099545e-02f, 3.13323302e-02f, 2.36362162e-02f, + 1.57827398e-02f, 7.83395091e-03f, -1.47413782e-04f, -8.09864153e-03f, -1.59574406e-02f, -2.36623595e-02f, + -3.11534717e-02f, -3.83725840e-02f, -4.52638947e-02f, -5.17743411e-02f, -5.78539729e-02f, -6.34564348e-02f, + -6.85392092e-02f, -7.30640654e-02f, -7.69971954e-02f, -8.03096220e-02f, -8.29772975e-02f, -8.49813524e-02f, + -8.63081836e-02f, -8.69495746e-02f, -8.69027157e-02f, -8.61702687e-02f, -8.47602668e-02f, -8.26860569e-02f, + -7.99661981e-02f, -7.66242997e-02f, -7.26887788e-02f, -6.81926752e-02f, -6.31733712e-02f, -5.76722279e-02f, + -5.17343061e-02f, -4.54080069e-02f, -3.87446321e-02f, -3.17980032e-02f, -2.46239897e-02f, -1.72801497e-02f, + -9.82518156e-03f, -2.31845300e-03f, 5.18037510e-03f, 1.26119044e-02f, 1.99174857e-02f, 2.70395921e-02f, + 3.39223499e-02f, 4.05119404e-02f, 4.67570465e-02f, 5.26092142e-02f, 5.80232695e-02f, 6.29576539e-02f, + 6.73747113e-02f, 7.12410320e-02f, 7.45276905e-02f, 7.72104218e-02f, 7.92698394e-02f, 8.06915952e-02f, + 8.14664004e-02f, 8.15901977e-02f, 8.10640907e-02f, 7.98943315e-02f, 7.80922975e-02f, 7.56743792e-02f, + 7.26617861e-02f, 6.90804346e-02f, 6.49606433e-02f, 6.03370049e-02f, 5.52479503e-02f, 4.97355660e-02f, + 4.38451300e-02f, 3.76248662e-02f, 3.11254263e-02f, 2.43995757e-02f, 1.75017105e-02f, 1.04874823e-02f, + 3.41321948e-03f, -3.66433362e-03f, -1.06886566e-02f, -1.76037566e-02f, -2.43547422e-02f, -3.08881238e-02f, + -3.71523818e-02f, -4.30982377e-02f, -4.86791529e-02f, -5.38515978e-02f, -5.85754991e-02f, -6.28144137e-02f, + -6.65359631e-02f, -6.97119559e-02f, -7.23186409e-02f, -7.43369897e-02f, -7.57526047e-02f, -7.65560812e-02f, + -7.67428560e-02f, -7.63134051e-02f, -7.52730583e-02f, -7.36321241e-02f, -7.14055927e-02f, -6.86132027e-02f, + -6.52791213e-02f, -6.14318004e-02f, -5.71037475e-02f, -5.23312158e-02f, -4.71539306e-02f, -4.16147519e-02f, + -3.57593331e-02f, -2.96357023e-02f, -2.32939478e-02f, -1.67857228e-02f, -1.01639251e-02f, -3.48213128e-03f, + 3.20566951e-03f, 9.84566549e-03f, 1.63845318e-02f, 2.27699627e-02f, 2.89509937e-02f, 3.48784838e-02f, + 4.05054571e-02f, 4.57875191e-02f, 5.06831561e-02f, 5.51541055e-02f, 5.91656321e-02f, 6.26867948e-02f, + 6.56907214e-02f, 6.81547545e-02f, 7.00607045e-02f, 7.13948753e-02f, 7.21482790e-02f, 7.23165894e-02f, + 7.19002973e-02f, 7.09044846e-02f, 6.93390331e-02f, 6.72183039e-02f, 6.45611568e-02f, 6.13906537e-02f, + 5.77340810e-02f, 5.36223917e-02f, 4.90902973e-02f, 4.41756853e-02f, 3.89195025e-02f, 3.33653266e-02f, + 2.75589553e-02f, 2.15482187e-02f, 1.53823433e-02f, 9.11173206e-03f, 2.78750380e-03f, -3.53899736e-03f, + -9.81648845e-03f, -1.59942887e-02f, -2.20226002e-02f, -2.78530676e-02f, -3.34389835e-02f, -3.87358558e-02f, + -4.37015752e-02f, -4.82968641e-02f, -5.24856104e-02f, -5.62350079e-02f, -5.95160314e-02f, -6.23034090e-02f, + -6.45760369e-02f, -6.63170246e-02f, -6.75138263e-02f, -6.81583864e-02f, -6.82471093e-02f, -6.77809819e-02f, + -6.67654439e-02f, -6.52104027e-02f, -6.31301405e-02f, -6.05431381e-02f, -5.74719510e-02f, -5.39430121e-02f, + -4.99864152e-02f, -4.56356108e-02f, -4.09271785e-02f, -3.59005358e-02f, -3.05975021e-02f, -2.50620982e-02f, + -1.93400931e-02f, -1.34786109e-02f, -7.52582921e-03f, -1.53047296e-03f, 4.45846396e-03f, 1.03922252e-02f, + 1.62226043e-02f, 2.19024111e-02f, 2.73857927e-02f, 3.26286453e-02f, 3.75889120e-02f, 4.22270162e-02f, + 4.65060678e-02f, 5.03922602e-02f, 5.38550360e-02f, 5.68673912e-02f, 5.94061299e-02f, 6.14518959e-02f, + 6.29894927e-02f, 6.40078422e-02f, 6.45002081e-02f, 6.44641312e-02f, 6.39014463e-02f, 6.28183549e-02f, + 6.12252434e-02f, 5.91366226e-02f, 5.65710713e-02f, 5.35509478e-02f, 5.01023211e-02f, 4.62546289e-02f, + 4.20405644e-02f, 3.74956324e-02f, 3.26580309e-02f, 2.75681921e-02f, 2.22685138e-02f, 1.68029869e-02f, + 1.12168479e-02f, 5.55616360e-03f, -1.32475496e-04f, -5.80242145e-03f, -1.14072870e-02f, -1.69013632e-02f, + -2.22399629e-02f, -2.73798231e-02f, -3.22793559e-02f, -3.68992177e-02f, -4.12022700e-02f, -4.51542301e-02f, + -4.87237130e-02f, -5.18825743e-02f, -5.46061242e-02f, -5.68733215e-02f, -5.86668721e-02f, -5.99735198e-02f, + -6.07838952e-02f, -6.10928895e-02f, -6.08993923e-02f, -6.02064781e-02f, -5.90213291e-02f, -5.73550887e-02f, + -5.52228853e-02f, -5.26435817e-02f, -4.96396897e-02f, -4.62371294e-02f, -4.24650256e-02f, -3.83554628e-02f, + -3.39432096e-02f, -2.92654225e-02f, -2.43613233e-02f, -1.92718970e-02f, -1.40395616e-02f, -8.70771728e-03f, + -3.32056777e-03f, 2.07744785e-03f, 7.44190391e-03f, 1.27287222e-02f, 1.78946228e-02f, 2.28975002e-02f, + 2.76965843e-02f, 3.22530140e-02f, 3.65299534e-02f, 4.04930363e-02f, 4.41105069e-02f, 4.73536159e-02f, + 5.01967201e-02f, 5.26175750e-02f, 5.45974724e-02f, 5.61213729e-02f, 5.71780843e-02f, 5.77601946e-02f, + 5.78643759e-02f, 5.74910914e-02f, 5.66448597e-02f, 5.53340158e-02f, 5.35707338e-02f, 5.13708843e-02f, + 4.87538683e-02f, 4.57425137e-02f, 4.23627999e-02f, 3.86437075e-02f, 3.46169024e-02f, 3.03165387e-02f, + 2.57788894e-02f, 2.10421222e-02f, 1.61459251e-02f, 1.11311994e-02f, 6.03970466e-03f, 9.13695817e-04f, + -4.20433431e-03f, -9.27218149e-03f, -1.42480682e-02f, -1.90911878e-02f, -2.37618648e-02f, -2.82220093e-02f, + -3.24353766e-02f, -3.63678336e-02f, -3.99876924e-02f, -4.32659237e-02f, -4.61764207e-02f, -4.86961602e-02f, + -5.08054551e-02f, -5.24880386e-02f, -5.37312181e-02f, -5.45260166e-02f, -5.48671104e-02f, -5.47530531e-02f, + -5.41860463e-02f, -5.31721475e-02f, -5.17210363e-02f, -4.98459868e-02f, -4.75637647e-02f, -4.48944406e-02f, + -4.18612746e-02f, -3.84904206e-02f, -3.48107925e-02f, -3.08537797e-02f, -2.66529685e-02f, -2.22438695e-02f, + -1.76636682e-02f, -1.29507560e-02f, -8.14466071e-03f, -3.28544776e-03f, 1.58643018e-03f, 6.43050440e-03f, + 1.12067405e-02f, 1.58756642e-02f, 2.03989020e-02f, 2.47393345e-02f, 2.88614617e-02f, 3.27317634e-02f, + 3.63187992e-02f, 3.95936470e-02f, 4.25300387e-02f, 4.51045672e-02f, 4.72968940e-02f, 4.90899703e-02f, + 5.04700047e-02f, 5.14267809e-02f, 5.19535643e-02f, 5.20472034e-02f, 5.17082287e-02f, 5.09406434e-02f, + 4.97521048e-02f, 4.81537188e-02f, 4.61599131e-02f, 4.37884262e-02f, 4.10600706e-02f, 3.79985488e-02f, + 3.46302622e-02f, 3.09841217e-02f, 2.70912412e-02f, 2.29847199e-02f, 1.86992847e-02f, 1.42711599e-02f, + 9.73752669e-03f, 5.13643650e-03f, 5.06379454e-04f, -4.11408166e-03f, -8.68649476e-03f, -1.31729621e-02f, + -1.75363807e-02f, -2.17408089e-02f, -2.57516979e-02f, -2.95362143e-02f, -3.30635093e-02f, -3.63049622e-02f, + -3.92344048e-02f, -4.18283298e-02f, -4.40661418e-02f, -4.59301913e-02f, -4.74060505e-02f, -4.84825511e-02f, + -4.91518827e-02f, -4.94096235e-02f, -4.92548579e-02f, -4.86900251e-02f, -4.77210458e-02f, -4.63571741e-02f, + -4.46108878e-02f, -4.24979107e-02f, -4.00368564e-02f, -3.72492987e-02f, -3.41594108e-02f, -3.07938448e-02f, + -2.71814552e-02f, -2.33531198e-02f, -1.93413598e-02f, -1.51802063e-02f, -1.09048013e-02f, -6.55114338e-03f, + -2.15581014e-03f, 2.24443555e-03f, 6.61280814e-03f, 1.09129453e-02f, 1.51091980e-02f, 1.91667630e-02f, + 2.30522168e-02f, 2.67335907e-02f, 3.01807365e-02f, 3.33655579e-02f, 3.62622051e-02f, 3.88473226e-02f, + 4.11002204e-02f, 4.30030300e-02f, 4.45408790e-02f, 4.57019705e-02f, 4.64777109e-02f, 4.68627135e-02f, + 4.68549093e-02f, 4.64554958e-02f, 4.56689373e-02f, 4.45029599e-02f, 4.29683919e-02f, 4.10791386e-02f, + 3.88520159e-02f, 3.63066475e-02f, 3.34652385e-02f, 3.03523892e-02f, 2.69949681e-02f, 2.34217263e-02f, + 1.96632025e-02f, 1.57513974e-02f, 1.17194459e-02f, 7.60145677e-03f, 3.43215481e-03f, -7.53454950e-04f, + -4.92025229e-03f, -9.03345904e-03f, -1.30587503e-02f, -1.69627406e-02f, -2.07130441e-02f, -2.42787472e-02f, + -2.76304969e-02f, -3.07408842e-02f, -3.35845310e-02f, -3.61384026e-02f, -3.83819804e-02f, -4.02973364e-02f, + -4.18693911e-02f, -4.30859849e-02f, -4.39379525e-02f, -4.44192202e-02f, -4.45268207e-02f, -4.42609489e-02f, + -4.36249417e-02f, -4.26251693e-02f, -4.12710965e-02f, -3.95751119e-02f, -3.75524034e-02f, -3.52209020e-02f, + -3.26010732e-02f, -2.97156826e-02f, -2.65897306e-02f, -2.32501339e-02f, -1.97255230e-02f, -1.60459906e-02f, + -1.22428645e-02f, -8.34840613e-03f, -4.39555788e-03f, -4.17641093e-04f, 3.55186529e-03f, 7.47969548e-03f, + 1.13330289e-02f, 1.50796895e-02f, 1.86886063e-02f, 2.21298440e-02f, 2.53750227e-02f, 2.83974776e-02f, + 3.11724713e-02f, 3.36774564e-02f, 3.58921485e-02f, 3.77988281e-02f, 3.93823848e-02f, 4.06304645e-02f, + 4.15335460e-02f, 4.20850895e-02f, 4.22814530e-02f, 4.21220657e-02f, 4.16092724e-02f, 4.07484568e-02f, + 3.95478256e-02f, 3.80185099e-02f, 3.61742882e-02f, 3.40316228e-02f, 3.16093467e-02f, 2.89286854e-02f, + 2.60129143e-02f, 2.28872072e-02f, 1.95785162e-02f, 1.61151429e-02f, 1.25266872e-02f, 8.84367289e-03f, + 5.09737541e-03f, 1.31946573e-03f, -2.45819207e-03f, -6.20382907e-03f, -9.88599514e-03f, -1.34739714e-02f, + -1.69377975e-02f, -2.02487225e-02f, -2.33793144e-02f, -2.63038233e-02f, -2.89981802e-02f, -3.14404213e-02f, + -3.36107546e-02f, -3.54916723e-02f, -3.70682427e-02f, -3.83280672e-02f, -3.92614736e-02f, -3.98615776e-02f, + -4.01243243e-02f, -4.00484517e-02f, -3.96356708e-02f, -3.88903731e-02f, -3.78198781e-02f, -3.64341365e-02f, + -3.47457457e-02f, -3.27698392e-02f, -3.05238882e-02f, -2.80276282e-02f, -2.53028218e-02f, -2.23730957e-02f, + -1.92637467e-02f, -1.60015029e-02f, -1.26142882e-02f, -9.13104283e-03f, -5.58138981e-03f, -1.99542434e-03f, + 1.59649307e-03f, 5.16408174e-03f, 8.67737144e-03f, 1.21068581e-02f, 1.54239205e-02f, 1.86009100e-02f, + 2.16114772e-02f, 2.44306994e-02f, 2.70354163e-02f, 2.94042665e-02f, 3.15179985e-02f, 3.33595356e-02f, + 3.49141593e-02f, 3.61696229e-02f, 3.71161871e-02f, 3.77468512e-02f, 3.80571878e-02f, 3.80455485e-02f, + 3.77129900e-02f, 3.70632810e-02f, 3.61028508e-02f, 3.48407199e-02f, 3.32884428e-02f, 3.14600053e-02f, + 2.93716228e-02f, 2.70417408e-02f, 2.44907277e-02f, 2.17407576e-02f, 1.88156734e-02f, 1.57406803e-02f, + 1.25421761e-02f, 9.24754692e-03f, 5.88488640e-03f, 2.48280587e-03f, -9.29864758e-04f, -4.32426314e-03f, + -7.67179184e-03f, -1.09442952e-02f, -1.41143886e-02f, -1.71555974e-02f, -2.00425787e-02f, -2.27514891e-02f, + -2.52599054e-02f, -2.75472706e-02f, -2.95949315e-02f, -3.13863062e-02f, -3.29069832e-02f, -3.41450096e-02f, + -3.50907101e-02f, -3.57369992e-02f, -3.60793163e-02f, -3.61156751e-02f, -3.58467080e-02f, -3.52755740e-02f, + -3.44080617e-02f, -3.32523628e-02f, -3.18191314e-02f, -3.01213186e-02f, -2.81740846e-02f, -2.59946393e-02f, + -2.36021125e-02f, -2.10173975e-02f, -1.82629132e-02f, -1.53624700e-02f, -1.23410560e-02f, -9.22456599e-03f, + -6.03967755e-03f, -2.81350877e-03f, 4.26514319e-04f, 3.65292660e-03f, 6.83848944e-03f, 9.95638508e-03f, + 1.29804234e-02f, 1.58853076e-02f, 1.86468203e-02f, 2.12420277e-02f, 2.36494909e-02f, 2.58493792e-02f, + 2.78237450e-02f, 2.95565060e-02f, 3.10338053e-02f, 3.22438572e-02f, 3.31772716e-02f, 3.38269627e-02f, + 3.41883176e-02f, 3.42591610e-02f, 3.40397435e-02f, 3.35328606e-02f, 3.27436351e-02f, 3.16796573e-02f, + 3.03507246e-02f, 2.87689689e-02f, 2.69484839e-02f, 2.49054827e-02f, 2.26579086e-02f, 2.02254442e-02f, + 1.76292617e-02f, 1.48918382e-02f, 1.20368159e-02f, 9.08872468e-03f, 6.07283273e-03f, 3.01489838e-03f, + -5.90212194e-05f, -3.12287666e-03f, -6.15069532e-03f, -9.11695091e-03f, -1.19967033e-02f, -1.47657868e-02f, + -1.74011004e-02f, -1.98807214e-02f, -2.21841025e-02f, -2.42922632e-02f, -2.61879368e-02f, -2.78557311e-02f, + -2.92821801e-02f, -3.04559562e-02f, -3.13678907e-02f, -3.20110632e-02f, -3.23808087e-02f, -3.24749193e-02f, + -3.22933847e-02f, -3.18386269e-02f, -3.11153366e-02f, -3.01304804e-02f, -2.88932552e-02f, -2.74148734e-02f, + -2.57086673e-02f, -2.37898314e-02f, -2.16752343e-02f, -1.93835013e-02f, -1.69345799e-02f, -1.43497284e-02f, + -1.16513243e-02f, -8.86259097e-03f, -6.00748525e-03f, -3.11044903e-03f, -1.96143386e-04f, 2.71056658e-03f, + 5.58512222e-03f, 8.40318833e-03f, 1.11410160e-02f, 1.37756382e-02f, 1.62850338e-02f, 1.86482666e-02f, + 2.08457445e-02f, 2.28593437e-02f, 2.46725329e-02f, 2.62705694e-02f, 2.76405329e-02f, 2.87715470e-02f, + 2.96547092e-02f, 3.02833419e-02f, 3.06529059e-02f, 3.07610441e-02f, 3.06076742e-02f, 3.01949567e-02f, + 2.95271502e-02f, 2.86107876e-02f, 2.74543883e-02f, 2.60685701e-02f, 2.44657863e-02f, 2.26603655e-02f, + 2.06682557e-02f, 1.85070033e-02f, 1.61954603e-02f, 1.37537720e-02f, 1.12030588e-02f, 8.56537064e-03f, + 5.86336215e-03f, 3.12021752e-03f, 3.59345288e-04f, -2.39571357e-03f, -5.12158252e-03f, -7.79518527e-03f, + -1.03939536e-02f, -1.28961026e-02f, -1.52805838e-02f, -1.75275761e-02f, -1.96183935e-02f, -2.15357712e-02f, + -2.32639542e-02f, -2.47888545e-02f, -2.60981899e-02f, -2.71814567e-02f, -2.80302370e-02f, -2.86380088e-02f, + -2.90003996e-02f, -2.91151172e-02f, -2.89819544e-02f, -2.86028697e-02f, -2.79818317e-02f, -2.71249297e-02f, + -2.60401957e-02f, -2.47375751e-02f, -2.32288414e-02f, -2.15275091e-02f, -1.96486443e-02f, -1.76087964e-02f, + -1.54258426e-02f, -1.31187994e-02f, -1.07076937e-02f, -8.21335282e-03f, -5.65730582e-03f, -3.06143405e-03f, + -4.47990175e-04f, 2.16074548e-03f, 4.74260737e-03f, 7.27569124e-03f, 9.73864733e-03f, 1.21106824e-02f, + 1.43719841e-02f, 1.65036001e-02f, 1.84878471e-02f, 2.03083286e-02f, 2.19500531e-02f, 2.33996493e-02f, + 2.46453861e-02f, 2.56773512e-02f, 2.64874345e-02f, 2.70694463e-02f, 2.74192279e-02f, 2.75344951e-02f, + 2.74150667e-02f, 2.70627089e-02f, 2.64811913e-02f, 2.56761950e-02f, 2.46553112e-02f, 2.34279326e-02f, + 2.20051823e-02f, 2.03998041e-02f, 1.86260730e-02f, 1.66996483e-02f, 1.46373888e-02f, 1.24573628e-02f, + 1.01784699e-02f, 7.82046099e-03f, 5.40366356e-03f, 2.94886537e-03f, 4.77074685e-04f, -1.99056008e-03f, + -4.43309957e-03f, -6.82975366e-03f, -9.16032780e-03f, -1.14051392e-02f, -1.35453571e-02f, -1.55631186e-02f, + -1.74416221e-02f, -1.91653203e-02f, -2.07200521e-02f, -2.20931290e-02f, -2.32734389e-02f, -2.42515770e-02f, + -2.50198790e-02f, -2.55724740e-02f, -2.59053977e-02f, -2.60165073e-02f, -2.59056121e-02f, -2.55744100e-02f, + -2.50263861e-02f, -2.42670139e-02f, -2.33034172e-02f, -2.21444752e-02f, -2.08007704e-02f, -1.92843016e-02f, + -1.76086143e-02f, -1.57885066e-02f, -1.38399632e-02f, -1.17800468e-02f, -9.62665505e-03f, -7.39846180e-03f, + -5.11473979e-03f, -2.79509520e-03f, -4.59475153e-04f, 1.87219411e-03f, 4.18004886e-03f, 6.44446028e-03f, + 8.64630036e-03f, 1.07670050e-02f, 1.27887263e-02f, 1.46946183e-02f, 1.64687696e-02f, 1.80965074e-02f, + 1.95644657e-02f, 2.08606409e-02f, 2.19745569e-02f, 2.28973400e-02f, 2.36217678e-02f, 2.41423032e-02f, + 2.44552329e-02f, 2.45585559e-02f, 2.44521268e-02f, 2.41375247e-02f, 2.36181843e-02f, 2.28991883e-02f, + 2.19873596e-02f, 2.08911372e-02f, 1.96204854e-02f, 1.81868423e-02f, 1.66029686e-02f, 1.48829260e-02f, + 1.30418196e-02f, 1.10957823e-02f, 9.06176569e-03f, 6.95742371e-03f, 4.80095797e-03f, 2.61094572e-03f, + 4.06163422e-04f, -1.79448120e-03f, -3.97227507e-03f, -6.10867089e-03f, -8.18559133e-03f, -1.01855447e-02f, + -1.20916775e-02f, -1.38880736e-02f, -1.55597947e-02f, -1.70929424e-02f, -1.84749792e-02f, -1.96945768e-02f, + -2.07419008e-02f, -2.16086011e-02f, -2.22879060e-02f, -2.27746496e-02f, -2.30653527e-02f, -2.31582122e-02f, + -2.30530853e-02f, -2.27516002e-02f, -2.22569518e-02f, -2.15740851e-02f, -2.07094459e-02f, -1.96710504e-02f, + -1.84683607e-02f, -1.71122258e-02f, -1.56147530e-02f, -1.39891960e-02f, -1.22499260e-02f, -1.04121226e-02f, + -8.49187069e-03f, -6.50583812e-03f, -4.47121574e-03f, -2.40553061e-03f, -3.26560349e-04f, 1.74792849e-03f, + 3.80020986e-03f, 5.81284812e-03f, 7.76878436e-03f, 9.65152189e-03f, 1.14452321e-02f, 1.31348903e-02f, + 1.47064602e-02f, 1.61469015e-02f, 1.74443880e-02f, 1.85883329e-02f, 1.95694960e-02f, 2.03800747e-02f, + 2.10137416e-02f, 2.14657028e-02f, 2.17327470e-02f, 2.18132189e-02f, 2.17071096e-02f, 2.14159688e-02f, + 2.09429396e-02f, 2.02927056e-02f, 1.94714591e-02f, 1.84867806e-02f, 1.73476996e-02f, 1.60644888e-02f, + 1.46486021e-02f, 1.31126305e-02f, 1.14700918e-02f, 9.73543186e-03f, 7.92379251e-03f, 6.05090462e-03f, + 4.13301608e-03f, 2.18669055e-03f, 2.28581333e-04f, -1.72441072e-03f, -3.65572200e-03f, -5.54887990e-03f, + -7.38782061e-03f, -9.15706782e-03f, -1.08417082e-02f, -1.24276657e-02f, -1.39017311e-02f, -1.52516970e-02f, + -1.64664949e-02f, -1.75361817e-02f, -1.84521823e-02f, -1.92071599e-02f, -1.97953056e-02f, -2.02121243e-02f, + -2.04547147e-02f, -2.05216098e-02f, -2.04128534e-02f, -2.01300439e-02f, -1.96761990e-02f, -1.90558123e-02f, + -1.82748056e-02f, -1.73404276e-02f, -1.62612067e-02f, -1.50469098e-02f, -1.37084115e-02f, -1.22575769e-02f, + -1.07072432e-02f, -9.07102930e-03f, -7.36320826e-03f, -5.59869147e-03f, -3.79270806e-03f, -1.96092013e-03f, + -1.19027325e-04f, 1.71713152e-03f, 3.53191747e-03f, 5.30986343e-03f, 7.03590331e-03f, 8.69547560e-03f, + 1.02746006e-02f, 1.17601122e-02f, 1.31396009e-02f, 1.44016653e-02f, 1.55359973e-02f, 1.65332483e-02f, + 1.73855033e-02f, 1.80859434e-02f, 1.86291305e-02f, 1.90110277e-02f, 1.92289384e-02f, 1.92815880e-02f, + 1.91691688e-02f, 1.88932135e-02f, 1.84567183e-02f, 1.78639790e-02f, 1.71206377e-02f, 1.62336473e-02f, + 1.52110920e-02f, 1.40622274e-02f, 1.27973510e-02f, 1.14277163e-02f, 9.96541843e-03f, 8.42333112e-03f, + 6.81491991e-03f, 5.15420944e-03f, 3.45559138e-03f, 1.73374462e-03f, 3.49154958e-06f, -1.72033182e-03f, + -3.42300908e-03f, -5.09002877e-03f, -6.70728983e-03f, -8.26110592e-03f, -9.73843101e-03f, -1.11269177e-02f, + -1.24149972e-02f, -1.35920411e-02f, -1.46483675e-02f, -1.55754162e-02f, -1.63657097e-02f, -1.70130158e-02f, + -1.75123254e-02f, -1.78599156e-02f, -1.80533642e-02f, -1.80916471e-02f, -1.79749596e-02f, -1.77049199e-02f, + -1.72844059e-02f, -1.67175734e-02f, -1.60098348e-02f, -1.51677846e-02f, -1.41991369e-02f, -1.31126308e-02f, + -1.19180614e-02f, -1.06260158e-02f, -9.24795820e-03f, -7.79599691e-03f, -6.28282689e-03f, -4.72166017e-03f, + -3.12602130e-03f, -1.50971188e-03f, 1.13358008e-04f, 1.72924640e-03f, 3.32419869e-03f, 4.88457483e-03f, + 6.39719332e-03f, 7.84928507e-03f, 9.22860374e-03f, 1.05236737e-02f, 1.17237027e-02f, 1.28187631e-02f, + 1.37999219e-02f, 1.46591627e-02f, 1.53896448e-02f, 1.59855771e-02f, 1.64423748e-02f, 1.67566705e-02f, + 1.69263151e-02f, 1.69504088e-02f, 1.68293192e-02f, 1.65646048e-02f, 1.61591292e-02f, 1.56168830e-02f, + 1.49430466e-02f, 1.41438870e-02f, 1.32267343e-02f, 1.21999194e-02f, 1.10726150e-02f, 9.85491162e-03f, + 8.55755480e-03f, 7.19198626e-03f, 5.77013714e-03f, 4.30443841e-03f, 2.80758857e-03f, 1.29252809e-03f, + -2.27683018e-04f, -1.74000213e-03f, -3.23153173e-03f, -4.68956247e-03f, -6.10171563e-03f, -7.45612506e-03f, + -8.74136426e-03f, -9.94672023e-03f, -1.10621909e-02f, -1.20785406e-02f, -1.29874795e-02f, -1.37816456e-02f, + -1.44546479e-02f, -1.50012468e-02f, -1.54172106e-02f, -1.56995155e-02f, -1.58462779e-02f, -1.58567437e-02f, + -1.57313825e-02f, -1.54717967e-02f, -1.50807184e-02f, -1.45620705e-02f, -1.39207297e-02f, -1.31627253e-02f, + -1.22950111e-02f, -1.13254027e-02f, -1.02626834e-02f, -9.11627932e-03f, -7.89634415e-03f, -6.61364765e-03f, + -5.27939952e-03f, -3.90525708e-03f, -2.50314317e-03f, -1.08517576e-03f, 3.36418391e-04f, 1.74945190e-03f, + 3.14186033e-03f, 4.50178261e-03f, 5.81769448e-03f, 7.07851939e-03f, 8.27365386e-03f, 9.39310326e-03f, + 1.04276320e-02f, 1.13686527e-02f, 1.22085379e-02f, 1.29404450e-02f, 1.35585678e-02f, 1.40580446e-02f, + 1.44350939e-02f, 1.46869568e-02f, 1.48120098e-02f, 1.48096348e-02f, 1.46804295e-02f, 1.44259781e-02f, + 1.40489668e-02f, 1.35531325e-02f, 1.29432014e-02f, 1.22248563e-02f, 1.14046959e-02f, 1.04901687e-02f, + 9.48948107e-03f, 8.41156632e-03f, 7.26596347e-03f, 6.06280447e-03f, 4.81257444e-03f, 3.52622627e-03f, + 2.21492506e-03f, 8.89983592e-04f, -4.37153812e-04f, -1.75513167e-03f, -3.05265494e-03f, -4.31872834e-03f, + -5.54261874e-03f, -6.71396264e-03f, -7.82302244e-03f, -8.86045250e-03f, -9.81773278e-03f, -1.06869351e-02f, + -1.14610023e-02f, -1.21336754e-02f, -1.26995953e-02f, -1.31543908e-02f, -1.34945718e-02f, -1.37177266e-02f, + -1.38224110e-02f, -1.38082286e-02f, -1.36757739e-02f, -1.34266887e-02f, -1.30635886e-02f, -1.25900369e-02f, + -1.20105709e-02f, -1.13305978e-02f, -1.05563538e-02f, -9.69485926e-03f, -8.75389081e-03f, -7.74181164e-03f, + -6.66761679e-03f, -5.54076187e-03f, -4.37111830e-03f, -3.16893052e-03f, -1.94457115e-03f, -7.08705149e-04f, + 5.28079290e-04f, 1.75515870e-03f, 2.96204304e-03f, 4.13848585e-03f, 5.27451557e-03f, 6.36060039e-03f, + 7.38755863e-03f, 8.34692530e-03f, 9.23070802e-03f, 1.00316534e-02f, 1.07432528e-02f, 1.13597680e-02f, + 1.18763350e-02f, 1.22889283e-02f, 1.25944631e-02f, 1.27907515e-02f, 1.28765994e-02f, 1.28517102e-02f, + 1.27167966e-02f, 1.24734480e-02f, 1.21242371e-02f, 1.16725839e-02f, 1.11228281e-02f, 1.04800592e-02f, + 9.75022575e-03f, 8.93990424e-03f, 8.05644990e-03f, 7.10768601e-03f, 6.10205625e-03f, 5.04843878e-03f, + 3.95605458e-03f, 2.83441418e-03f, 1.69331277e-03f, 5.42568186e-04f, -6.07877124e-04f, -1.74818575e-03f, + -2.86860405e-03f, -3.95962685e-03f, -5.01201657e-03f, -6.01690058e-03f, -6.96589716e-03f, -7.85110424e-03f, + -8.66518231e-03f, -9.40145619e-03f, -1.00540095e-02f, -1.06175123e-02f, -1.10876024e-02f, -1.14606062e-02f, + -1.17337519e-02f, -1.19051415e-02f, -1.19737311e-02f, -1.19393909e-02f, -1.18028751e-02f, -1.15657387e-02f, + -1.12305357e-02f, -1.08005049e-02f, -1.02797519e-02f, -9.67318729e-03f, -8.98632838e-03f, -8.22543877e-03f, + -7.39737215e-03f, -6.50950785e-03f, -5.56975395e-03f, -4.58632875e-03f, -3.56792674e-03f, -2.52340823e-03f, + -1.46183597e-03f, -3.92391156e-04f, 6.75701684e-04f, 1.73331709e-03f, 2.77141530e-03f, 3.78118353e-03f, + 4.75407672e-03f, 5.68193005e-03f, 6.55698994e-03f, 7.37195674e-03f, 8.12013345e-03f, 8.79539509e-03f, + 9.39225030e-03f, 9.90597190e-03f, 1.03324819e-02f, 1.06685242e-02f, 1.09116177e-02f, 1.10600973e-02f, + 1.11130936e-02f, 1.10705983e-02f, 1.09333788e-02f, 1.07030445e-02f, 1.03819949e-02f, 9.97335332e-03f, + 9.48107464e-03f, 8.90968434e-03f, 8.26449756e-03f, 7.55132972e-03f, 6.77664458e-03f, 5.94731079e-03f, + 5.07073939e-03f, 4.15462520e-03f, 3.20700306e-03f, 2.23616222e-03f, 1.25050340e-03f, 2.58592562e-04f, + -7.31105992e-04f, -1.71003848e-03f, -2.66991104e-03f, -3.60254805e-03f, -4.50009626e-03f, -5.35500152e-03f, + -6.16013372e-03f, -6.90880302e-03f, -7.59484887e-03f, -8.21267759e-03f, -8.75730297e-03f, -9.22437062e-03f, + -9.61022818e-03f, -9.91196266e-03f, -1.01273334e-02f, -1.02549146e-02f, -1.02939949e-02f, -1.02446487e-02f, + -1.01077102e-02f, -9.88473930e-03f, -9.57804506e-03f, -9.19065219e-03f, -8.72623997e-03f, -8.18914967e-03f, + -7.58431711e-03f, -6.91725624e-03f, -6.19393169e-03f, -5.42085678e-03f, -4.60486090e-03f, -3.75314479e-03f, + -2.87318400e-03f, -1.97263669e-03f, -1.05936420e-03f, -1.41184633e-04f, 7.73935206e-04f, 1.67818033e-03f, + 2.56387121e-03f, 3.42348245e-03f, 4.24972968e-03f, 5.03575853e-03f, 5.77493594e-03f, 6.46117800e-03f, + 7.08885263e-03f, 7.65282423e-03f, 8.14856911e-03f, 8.57214716e-03f, 8.92027019e-03f, 9.19029194e-03f, + 9.38027470e-03f, 9.48895025e-03f, 9.51578399e-03f, 9.46091429e-03f, 9.32518284e-03f, 9.11016180e-03f, + 8.81806173e-03f, 8.45171440e-03f, 8.01466407e-03f, 7.51094572e-03f, 6.94521826e-03f, 6.32261691e-03f, + 5.64875255e-03f, 4.92963671e-03f, 4.17165548e-03f, 3.38149573e-03f, 2.56610069e-03f, 1.73253154e-03f, + 8.88083719e-04f, 4.00140997e-05f, -8.04377007e-04f, -1.63786496e-03f, -2.45336348e-03f, -3.24394120e-03f, + -4.00297149e-03f, -4.72406012e-03f, -5.40122825e-03f, -6.02886353e-03f, -6.60184564e-03f, -7.11547043e-03f, + -7.56567204e-03f, -7.94886879e-03f, -8.26207948e-03f, -8.50298133e-03f, -8.66984745e-03f, -8.76158174e-03f, + -8.77778600e-03f, -8.71866903e-03f, -8.58510255e-03f, -8.37858953e-03f, -8.10125332e-03f, -7.75580633e-03f, + -7.34555568e-03f, -6.87431135e-03f, -6.34642360e-03f, -5.76669768e-03f, -5.14031767e-03f, -4.47294897e-03f, + -3.77043291e-03f, -3.03903272e-03f, -2.28511456e-03f, -1.51527024e-03f, -7.36178447e-04f, 4.54225562e-05f, + 8.22859022e-04f, 1.58943109e-03f, 2.33866278e-03f, 3.06420334e-03f, 3.75990680e-03f, 4.42002538e-03f, + 5.03901750e-03f, 5.61180111e-03f, 6.13366220e-03f, 6.60043272e-03f, 7.00831931e-03f, 7.35414500e-03f, + 7.63524392e-03f, 7.84953557e-03f, 7.99547645e-03f, 8.07218955e-03f, 8.07933095e-03f, 8.01721906e-03f, + 7.88666864e-03f, 7.68919343e-03f, 7.42679720e-03f, 7.10202788e-03f, 6.71802523e-03f, 6.27832934e-03f, + 5.78702253e-03f, 5.24853339e-03f, 4.66776048e-03f, 4.04985033e-03f, 3.40032055e-03f, 2.72486114e-03f, + 2.02943382e-03f, 1.32005555e-03f, 6.02922229e-04f, -1.15810889e-04f, -8.29962401e-04f, -1.53344695e-03f, + -2.22024937e-03f, -2.88460828e-03f, -3.52090915e-03f, -4.12386103e-03f, -4.68844782e-03f, -5.21000854e-03f, + -5.68433641e-03f, -6.10753890e-03f, -6.47629357e-03f, -6.78770430e-03f, -7.03936807e-03f, -7.22944790e-03f, + -7.35662441e-03f, -7.42012069e-03f, -7.41971164e-03f, -7.35573757e-03f, -7.22905724e-03f, -7.04107429e-03f, + -6.79370122e-03f, -6.48940038e-03f, -6.13102314e-03f, -5.72192873e-03f, -5.26590521e-03f, -4.76707464e-03f, + -4.22993214e-03f, -3.65930825e-03f, -3.06022345e-03f, -2.43797793e-03f, -1.79803310e-03f, -1.14594988e-03f, + -4.87389180e-04f, 1.71985886e-04f, 8.26505744e-04f, 1.47057292e-03f, 2.09875564e-03f, 2.70572827e-03f, + 3.28638788e-03f, 3.83592350e-03f, 4.34975506e-03f, 4.82368759e-03f, 5.25383132e-03f, 5.63677359e-03f, + 5.96942535e-03f, 6.24924092e-03f, 6.47405650e-03f, 6.64226721e-03f, 6.75269253e-03f, 6.80469430e-03f, + 6.79815717e-03f, 6.73340631e-03f, 6.61130455e-03f, 6.43322863e-03f, 6.20094526e-03f, 5.91677710e-03f, + 5.58340169e-03f, 5.20393196e-03f, 4.78187614e-03f, 4.32106320e-03f, 3.82565711e-03f, 3.30005613e-03f, + 2.74895362e-03f, 2.17719303e-03f, 1.58978015e-03f, 9.91844057e-04f, 3.88540330e-04f, -2.14916878e-04f, + -8.13361192e-04f, -1.40168257e-03f, -1.97489740e-03f, -2.52818059e-03f, -3.05688539e-03f, -3.55662656e-03f, + -4.02326574e-03f, -4.45296958e-03f, -4.84228652e-03f, -5.18803438e-03f, -5.48755315e-03f, -5.73848611e-03f, + -5.93891991e-03f, -6.08745626e-03f, -6.18305471e-03f, -6.22520840e-03f, -6.21382472e-03f, -6.14928419e-03f, + -6.03244633e-03f, -5.86455879e-03f, -5.64736180e-03f, -5.38296537e-03f, -5.07389363e-03f, -4.72301916e-03f, + -4.33361321e-03f, -3.90915761e-03f, -3.45353173e-03f, -2.97077347e-03f, -2.46516689e-03f, -1.94119584e-03f, + -1.40340595e-03f, -8.56512644e-04f, -3.05232133e-04f, 2.45691031e-04f, 7.91538060e-04f, 1.32763724e-03f, + 1.84949345e-03f, 2.35267547e-03f, 2.83299113e-03f, 3.28645035e-03f, 3.70931698e-03f, 4.09812665e-03f, + 4.44973511e-03f, 4.76135341e-03f, 5.03050354e-03f, 5.25513155e-03f, 5.43353323e-03f, 5.56447821e-03f, + 5.64705544e-03f, 5.68083601e-03f, 5.66583437e-03f, 5.60238431e-03f, 5.49135375e-03f, 5.33391723e-03f, + 5.13169207e-03f, 4.88664671e-03f, 4.60113202e-03f, 4.27780860e-03f, 3.91964875e-03f, 3.52989866e-03f, + 3.11212090e-03f, 2.66999053e-03f, 2.20744344e-03f, 1.72859110e-03f, 1.23756351e-03f, 7.38678150e-04f, + 2.36236760e-04f, -2.65462378e-04f, -7.62072815e-04f, -1.24943395e-03f, -1.72337956e-03f, -2.17993754e-03f, + -2.61530935e-03f, -3.02588421e-03f, -3.40825196e-03f, -3.75935360e-03f, -4.07630652e-03f, -4.35660760e-03f, + -4.59808398e-03f, -4.79883718e-03f, -4.95743843e-03f, -5.07271280e-03f, -5.14393833e-03f, -5.17077608e-03f, + -5.15318763e-03f, -5.09164480e-03f, -4.98686807e-03f, -4.84002285e-03f, -4.65260103e-03f, -4.42642977e-03f, + -4.16366446e-03f, -3.86678300e-03f, -3.53847751e-03f, -3.18177292e-03f, -2.79986847e-03f, -2.39618401e-03f, + -1.97429017e-03f, -1.53788782e-03f, -1.09083664e-03f, -6.36973406e-04f, -1.80264329e-04f, 2.75399352e-04f, + 7.26104424e-04f, 1.16802598e-03f, 1.59744046e-03f, 2.01073128e-03f, 2.40446819e-03f, 2.77538562e-03f, + 3.12044615e-03f, 3.43683203e-03f, 3.72202393e-03f, 3.97374850e-03f, 4.19002854e-03f, 4.36925418e-03f, + 4.51006070e-03f, 4.61152219e-03f, 4.67293053e-03f, 4.69404975e-03f, 4.67490366e-03f, 4.61589307e-03f, + 4.51775252e-03f, 4.38154991e-03f, 4.20868532e-03f, 4.00082377e-03f, 3.75997274e-03f, 3.48836415e-03f, + 3.18851504e-03f, 2.86314343e-03f, 2.51519536e-03f, 2.14776743e-03f, 1.76411750e-03f, 1.36763070e-03f, + 9.61751835e-04f, 5.50052405e-04f, 1.36015058e-04f, -2.76720943e-04f, -6.84698152e-04f, -1.08442387e-03f, + -1.47253691e-03f, -1.84578853e-03f, -2.20105818e-03f, -2.53544188e-03f, -2.84616998e-03f, -3.13076058e-03f, + -3.38689733e-03f, -3.61260297e-03f, -3.80606518e-03f, -3.96589267e-03f, -4.09087232e-03f, -4.18013173e-03f, + -4.23315965e-03f, -4.24970953e-03f, -4.22981560e-03f, -4.17392494e-03f, -4.08267808e-03f, -3.95709577e-03f, + -3.79845153e-03f, -3.60829670e-03f, -3.38844338e-03f, -3.14094669e-03f, -2.86809742e-03f, -2.57237442e-03f, + -2.25643831e-03f, -1.92312165e-03f, -1.57535841e-03f, -1.21624129e-03f, -8.48868370e-04f, -4.76457354e-04f, + -1.02227062e-04f, 2.70659894e-04f, 6.38948957e-04f, 9.99596773e-04f, 1.34950884e-03f, 1.68579412e-03f, + 2.00565112e-03f, 2.30644176e-03f, 2.58570970e-03f, 2.84121989e-03f, 3.07087670e-03f, 3.27296771e-03f, + 3.44584695e-03f, 3.58825627e-03f, 3.69915439e-03f, 3.77779535e-03f, 3.82369144e-03f, 3.83666312e-03f, + 3.81678507e-03f, 3.76444486e-03f, 3.68027755e-03f, 3.56519883e-03f, 3.42038694e-03f, 3.24725992e-03f, + 3.04745181e-03f, 2.82287635e-03f, 2.57555610e-03f, 2.30778342e-03f, 2.02193938e-03f, 1.72060684e-03f, + 1.40642226e-03f, 1.08218540e-03f, 7.50708128e-04f, 4.14852040e-04f, 7.75468400e-05f, -2.58336678e-04f, + -5.89954675e-04f, -9.14464553e-04f, -1.22917409e-03f, -1.53142096e-03f, -1.81874942e-03f, -2.08875765e-03f, + -2.33925204e-03f, -2.56824046e-03f, -2.77387464e-03f, -2.95457151e-03f, -3.10891286e-03f, -3.23576957e-03f, + -3.33422309e-03f, -3.40361730e-03f, -3.44352432e-03f, -3.45380945e-03f, -3.43454926e-03f, -3.38612359e-03f, + -3.30910238e-03f, -3.20434413e-03f, -3.07289782e-03f, -2.91605448e-03f, -2.73534798e-03f, -2.53242439e-03f, + -2.30918427e-03f, -2.06766744e-03f, -1.81002532e-03f, -1.53857461e-03f, -1.25572213e-03f, -9.63956082e-04f, + -6.65804929e-04f, -3.63875198e-04f, -6.07622519e-05f, 2.40955893e-04f, 5.38685581e-04f, 8.29936911e-04f, + 1.11224977e-03f, 1.38328230e-03f, 1.64080028e-03f, 1.88265574e-03f, 2.10694670e-03f, 2.31181334e-03f, + 2.49567938e-03f, 2.65707799e-03f, 2.79477329e-03f, 2.90778929e-03f, 2.99526804e-03f, 3.05666792e-03f, + 3.09159989e-03f, 3.09996074e-03f, 3.08183486e-03f, 3.03757314e-03f, 2.96768997e-03f, 2.87296391e-03f, + 2.75438271e-03f, 2.61305979e-03f, 2.45041225e-03f, 2.26792371e-03f, 2.06728115e-03f, 1.85034398e-03f, + 1.61901728e-03f, 1.37543970e-03f, 1.12168235e-03f, 8.60048928e-04f, 5.92781787e-04f, 3.22217129e-04f, + 5.06437951e-05f, -2.19547817e-04f, -4.86132510e-04f, -7.46817210e-04f, -9.99443627e-04f, -1.24188233e-03f, + -1.47217245e-03f, -1.68839648e-03f, -1.88883105e-03f, -2.07184785e-03f, -2.23601745e-03f, -2.38006048e-03f, + -2.50288118e-03f, -2.60358292e-03f, -2.68144174e-03f, -2.73595307e-03f, -2.76679595e-03f, -2.77388624e-03f, + -2.75729794e-03f, -2.71735188e-03f, -2.65451985e-03f, -2.56952130e-03f, -2.46319204e-03f, -2.33660956e-03f, + -2.19096493e-03f, -2.02765268e-03f, -1.84815939e-03f, -1.65412932e-03f, -1.44731483e-03f, -1.22956426e-03f, + -1.00280075e-03f, -7.69022668e-04f, -5.30268510e-04f, -2.88586883e-04f, -4.60956253e-05f, 1.95186584e-04f, + 4.33161045e-04f, 6.65873263e-04f, 8.91328897e-04f, 1.10770620e-03f, 1.31316296e-03f, 1.50610067e-03f, + 1.68489795e-03f, 1.84814923e-03f, 1.99458512e-03f, 2.12304250e-03f, 2.23258384e-03f, 2.32237953e-03f, + 2.39181962e-03f, 2.44043032e-03f, 2.46796938e-03f, 2.47430968e-03f, 2.45957831e-03f, 2.42401283e-03f, + 2.36808884e-03f, 2.29238471e-03f, 2.19773378e-03f, 2.08501666e-03f, 1.95534528e-03f, 1.80993801e-03f, + 1.65014053e-03f, 1.47739854e-03f, 1.29329221e-03f, 1.09944593e-03f, 8.97596290e-04f, 6.89486470e-04f, + 4.76967544e-04f, 2.61847472e-04f, 4.59979030e-05f, -1.68770369e-04f, -3.80612759e-04f, -5.87744421e-04f, + -7.88452414e-04f, -9.81081718e-04f, -1.16402219e-03f, -1.33580811e-03f, -1.49504859e-03f, -1.64047131e-03f, + -1.77095587e-03f, -1.88548340e-03f, -1.98318254e-03f, -2.06335667e-03f, -2.12544333e-03f, -2.16903096e-03f, + -2.19389731e-03f, -2.19994674e-03f, -2.18726700e-03f, -2.15609170e-03f, -2.10683457e-03f, -2.04002290e-03f, + -1.95633800e-03f, -1.85665258e-03f, -1.74189023e-03f, -1.61313165e-03f, -1.47159921e-03f, -1.31856217e-03f, + -1.15541374e-03f, -9.83590913e-04f, -8.04645529e-04f, -6.20138811e-04f, -4.31664744e-04f, -2.40859759e-04f, + -4.93718861e-05f, 1.41183920e-04f, 3.29184443e-04f, 5.13049545e-04f, 6.91252710e-04f, 8.62329668e-04f, + 1.02486089e-03f, 1.17753306e-03f, 1.31912530e-03f, 1.44851584e-03f, 1.56468190e-03f, 1.66675270e-03f, + 1.75393226e-03f, 1.82562545e-03f, 1.88129935e-03f, 1.92062935e-03f, 1.94336360e-03f, 1.94946381e-03f, + 1.93898469e-03f, 1.91211060e-03f, 1.86925265e-03f, 1.81081128e-03f, 1.73745800e-03f, 1.64989979e-03f, + 1.54896085e-03f, 1.43565148e-03f, 1.31095906e-03f, 1.17607031e-03f, 1.03219054e-03f, 8.80596006e-04f, + 7.22634695e-04f, 5.59715925e-04f, 3.93223384e-04f, 2.24602808e-04f, 5.53223372e-05f, -1.13204206e-04f, + -2.79527886e-04f, -4.42273875e-04f, -6.00090187e-04f, -7.51646708e-04f, -8.95738714e-04f, -1.03117771e-03f, + -1.15687770e-03f, -1.27187587e-03f, -1.37523688e-03f, -1.46618576e-03f, -1.54403989e-03f, -1.60825931e-03f, + -1.65836399e-03f, -1.69405240e-03f, -1.71514183e-03f, -1.72154028e-03f, -1.71331327e-03f, -1.69063272e-03f, + -1.65381037e-03f, -1.60326168e-03f, -1.53948863e-03f, -1.46318779e-03f, -1.37503217e-03f, -1.27591969e-03f, + -1.16672308e-03f, -1.04846883e-03f, -9.22232848e-04f, -7.89108246e-04f, -6.50329911e-04f, -5.07057241e-04f, + -3.60579584e-04f, -2.12138548e-04f, -6.30166060e-05f, 8.55107333e-05f, 2.32212191e-04f, 3.75851456e-04f, + 5.15213418e-04f, 6.49182851e-04f, 7.76642588e-04f, 8.96585347e-04f, 1.00803198e-03f, 1.11010987e-03f, + 1.20203475e-03f, 1.28308439e-03f, 1.35268783e-03f, 1.41030687e-03f, 1.45558664e-03f, 1.48819124e-03f, + 1.50798717e-03f, 1.51486502e-03f, 1.50888467e-03f, 1.49022209e-03f, 1.45906012e-03f, 1.41583581e-03f, + 1.36095722e-03f, 1.29499749e-03f, 1.21859138e-03f, 1.13249419e-03f, 1.03745344e-03f, 9.34384957e-04f, + 8.24209226e-04f, 7.07921644e-04f, 5.86535461e-04f, 4.61118668e-04f, 3.32797940e-04f, 2.02615430e-04f, + 7.17560319e-05f, -5.87215139e-05f, -1.87700771e-04f, -3.14093799e-04f, -4.36855019e-04f, -5.54982470e-04f, + -6.67514567e-04f, -7.73539543e-04f, -8.72216549e-04f, -9.62754726e-04f, -1.04446836e-03f, -1.11673823e-03f, + -1.17901020e-03f, -1.23084835e-03f, -1.27191263e-03f, -1.30189831e-03f, -1.32066941e-03f, -1.32816613e-03f, + -1.32437715e-03f, -1.30944714e-03f, -1.28360668e-03f, -1.24710492e-03f, -1.20038313e-03f, -1.14391116e-03f, + -1.07822250e-03f, -1.00394823e-03f, -9.21799577e-04f, -8.32520513e-04f, -7.36916195e-04f, -6.35853312e-04f, + -5.30218398e-04f, -4.20950684e-04f, -3.08981087e-04f, -1.95310152e-04f, -8.08721649e-05f, 3.33481785e-05f, + 1.46369769e-04f, 2.57271691e-04f, 3.65123878e-04f, 4.69053422e-04f, 5.68205019e-04f, 6.61777482e-04f, + 7.49035427e-04f, 8.29295760e-04f, 9.01919035e-04f, 9.66370937e-04f, 1.02218113e-03f, 1.06892877e-03f, + 1.10630552e-03f, 1.13406370e-03f, 1.15204451e-03f, 1.16019052e-03f, 1.15848806e-03f, 1.14706630e-03f, + 1.12606449e-03f, 1.09574589e-03f, 1.05645362e-03f, 1.00859266e-03f, 9.52601766e-04f, 8.89057609e-04f, + 8.18535938e-04f, 7.41697389e-04f, 6.59241262e-04f, 5.71884368e-04f, 4.80414698e-04f, 3.85677252e-04f, + 2.88406796e-04f, 1.89536836e-04f, 8.98491837e-05f, -9.79888746e-06f, -1.08531507e-04f, -2.05575498e-04f, + -3.00092231e-04f, -3.91327952e-04f, -4.78537671e-04f, -5.61003964e-04f, -6.38090388e-04f, -7.09209697e-04f, + -7.73747838e-04f, -8.31297964e-04f, -8.81364804e-04f, -9.23641236e-04f, -9.57793553e-04f, -9.83624619e-04f, + -1.00098424e-03f, -1.00979404e-03f, -1.01003977e-03f, -1.00180772e-03f, -9.85219816e-04f, -9.60506778e-04f, + -9.27905874e-04f, -8.87790902e-04f, -8.40553609e-04f, -7.86632276e-04f, -7.26559669e-04f, -6.60872173e-04f, + -5.90177860e-04f, -5.15099219e-04f, -4.36341554e-04f, -3.54526447e-04f, -2.70436804e-04f, -1.84757234e-04f, + -9.82406108e-05f, -1.16228429e-05f, 7.44116225e-05f, 1.59099493e-04f, 2.41739119e-04f, 3.21707034e-04f, + 3.98276352e-04f, 4.70887555e-04f, 5.38973046e-04f, 6.01940918e-04f, 6.59368174e-04f, 7.10783030e-04f, + 7.55802336e-04f, 7.94127086e-04f, 8.25478803e-04f, 8.49639386e-04f, 8.66487952e-04f, 8.75935969e-04f, + 8.77948893e-04f, 8.72611584e-04f, 8.59994515e-04f, 8.40271458e-04f, 8.13696181e-04f, 7.80491851e-04f, + 7.41053306e-04f, 6.95727202e-04f, 6.44936090e-04f, 5.89181503e-04f, 5.28946796e-04f, 4.64790448e-04f, + 3.97272420e-04f, 3.27000597e-04f, 2.54559578e-04f, 1.80597276e-04f, 1.05760446e-04f, 3.06209047e-05f, + -4.41172003e-05f, -1.17884760e-04f, -1.90032814e-04f, -2.60000039e-04f, -3.27213235e-04f, -3.91110007e-04f, + -4.51226928e-04f, -5.07042112e-04f, -5.58194586e-04f, -6.04189222e-04f, -6.44816381e-04f, -6.79653847e-04f, + -7.08557315e-04f, -7.31282579e-04f, -7.47702169e-04f, -7.57731688e-04f, -7.61359812e-04f, -7.58589885e-04f, + -7.49503361e-04f, -7.34226582e-04f, -7.12935677e-04f, -6.85882645e-04f, -6.53307567e-04f, -6.15569562e-04f, + -5.72978650e-04f, -5.25977418e-04f, -4.74963705e-04f, -4.20426590e-04f, -3.62819514e-04f, -3.02647353e-04f, + -2.40497241e-04f, -1.76810216e-04f, -1.12210871e-04f, -4.71976690e-05f, 1.76624641e-05f, 8.18440593e-05f, + 1.44804207e-04f, 2.06021410e-04f, 2.65025446e-04f, 3.21327783e-04f, 3.74487008e-04f, 4.24062432e-04f, + 4.69715655e-04f, 5.11042943e-04f, 5.47794530e-04f, 5.79655168e-04f, 6.06446384e-04f, 6.27934546e-04f, + 6.44010762e-04f, 6.54614698e-04f, 6.59636425e-04f, 6.59157826e-04f, 6.53158826e-04f, 6.41794049e-04f, + 6.25154916e-04f, 6.03470855e-04f, 5.76917242e-04f, 5.45789736e-04f, 5.10368292e-04f, 4.70998661e-04f, + 4.28021656e-04f, 3.81834126e-04f, 3.32863326e-04f, 2.81489629e-04f, 2.28231239e-04f, 1.73484261e-04f, + 1.17756607e-04f, 6.14881351e-05f, 5.17778269e-06f, -5.07352374e-05f, -1.05745987e-04f, -1.59454662e-04f, + -2.11394268e-04f, -2.61151905e-04f, -3.08351703e-04f, -3.52598590e-04f, -3.93545002e-04f, -4.30916147e-04f, + -4.64387406e-04f, -4.93756593e-04f, -5.18755281e-04f, -5.39265493e-04f, -5.55137934e-04f, -5.66259303e-04f, + -5.72606783e-04f, -5.74140344e-04f, -5.70903292e-04f, -5.62934741e-04f, -5.50388898e-04f, -5.33351962e-04f, + -5.12028510e-04f, -4.86612455e-04f, -4.57392981e-04f, -4.24578939e-04f, -3.88503808e-04f, -3.49487518e-04f, + -3.07895836e-04f, -2.64036522e-04f, -2.18356445e-04f, -1.71198300e-04f, -1.22998901e-04f, -7.41392080e-05f, + -2.50280393e-05f, 2.38852047e-05f, 7.22663332e-05f, 1.19659647e-04f, 1.65718806e-04f, 2.10055385e-04f, + 2.52324173e-04f, 2.92190427e-04f, 3.29337577e-04f, 3.63510150e-04f, 3.94385715e-04f, 4.21803288e-04f, + 4.45519433e-04f, 4.65391876e-04f, 4.81270460e-04f, 4.93057625e-04f, 5.00688030e-04f, 5.04121708e-04f, + 5.03379627e-04f, 4.98485604e-04f, 4.89499566e-04f, 4.76539317e-04f, 4.59760023e-04f, 4.39274612e-04f, + 4.15334876e-04f, 3.88103885e-04f, 3.57902146e-04f, 3.24908089e-04f, 2.89490480e-04f, 2.51922687e-04f, + 2.12512220e-04f, 1.71637404e-04f, 1.29609890e-04f, 8.67866183e-05f, 4.35312276e-05f, 1.98808307e-07f, + -4.28589070e-05f, -8.52865394e-05f, -1.26765698e-04f, -1.66922292e-04f, -2.05456466e-04f, -2.42095652e-04f, + -2.76487494e-04f, -3.08425602e-04f, -3.37638832e-04f, -3.63923042e-04f, -3.87022898e-04f, -4.06875144e-04f, + -4.23245129e-04f, -4.36071615e-04f, -4.45236993e-04f, -4.50724682e-04f, -4.52491230e-04f, -4.50548104e-04f, + -4.44936790e-04f, -4.35725612e-04f, -4.22987381e-04f, -4.06882738e-04f, -3.87548587e-04f, -3.65123104e-04f, + -3.39860288e-04f, -3.11947486e-04f, -2.81618569e-04f, -2.49166817e-04f, -2.14824344e-04f, -1.78876370e-04f, + -1.41684861e-04f, -1.03466427e-04f, -6.45996088e-05f, -2.53738050e-05f, 1.39035721e-05f, 5.28977578e-05f, + 9.13010773e-05f, 1.28809554e-04f, 1.65139924e-04f, 2.00005346e-04f, 2.33095696e-04f, 2.64232233e-04f, + 2.93070034e-04f, 3.19508024e-04f, 3.43252648e-04f, 3.64165224e-04f, 3.82074036e-04f, 3.96868082e-04f, + 4.08408250e-04f, 4.16671952e-04f, 4.21556517e-04f, 4.23035822e-04f, 4.21172111e-04f, 4.15928838e-04f, + 4.07377025e-04f, 3.95568598e-04f, 3.80628038e-04f, 3.62729177e-04f, 3.41921136e-04f, 3.18489958e-04f, + 2.92497406e-04f, 2.64266550e-04f, 2.33955571e-04f, 2.01809261e-04f, 1.68092145e-04f, 1.33141461e-04f, + 9.71043460e-05f, 6.03452880e-05f, 2.31264055e-05f, -1.43105089e-05f, -5.15607083e-05f, -8.84833364e-05f, + -1.24679461e-04f, -1.59910519e-04f, -1.93952723e-04f, -2.26496145e-04f, -2.57307566e-04f, -2.86175538e-04f, + -3.12853472e-04f, -3.37140613e-04f, -3.58914997e-04f, -3.77932329e-04f, -3.94117065e-04f, -4.07317063e-04f, + -4.17422308e-04f, -4.24419479e-04f, -4.28161231e-04f, -4.28700484e-04f, -4.26016659e-04f, -4.20088126e-04f, + -4.11009185e-04f, -3.98835037e-04f, -3.83585114e-04f, -3.65493072e-04f, -3.44616197e-04f, -3.21064387e-04f, + -2.95119418e-04f, -2.66863117e-04f, -2.36549174e-04f, -2.04391686e-04f, -1.70585806e-04f, -1.35432614e-04f, + -9.91006984e-05f, -6.19152828e-05f, -2.41012311e-05f, 1.40621144e-05f, 5.22867497e-05f, 9.03199843e-05f, + 1.27917614e-04f, 1.64740292e-04f, 2.00634478e-04f, 2.35261402e-04f, 2.68377430e-04f, 2.99818019e-04f, + 3.29273634e-04f, 3.56562766e-04f, 3.81532332e-04f, 4.03948113e-04f, 4.23655375e-04f, 4.40488930e-04f, + 4.54376777e-04f, 4.65137195e-04f, 4.72679704e-04f, 4.77014073e-04f, 4.77982201e-04f, 4.75625277e-04f, + 4.69878507e-04f, 4.60802987e-04f, 4.48367418e-04f, 4.32641679e-04f, 4.13709630e-04f, 3.91634147e-04f, + 3.66512902e-04f, 3.38481392e-04f, 3.07634938e-04f, 2.74189182e-04f, 2.38229594e-04f, 1.99985879e-04f, + 1.59632210e-04f, 1.17351364e-04f, 7.33404728e-05f, 2.78844831e-05f, -1.89099461e-05f, -6.67343638e-05f, + -1.15367449e-04f, -1.64649983e-04f, -2.14224348e-04f, -2.64019844e-04f, -3.13654244e-04f, -3.62990333e-04f, + -4.11800705e-04f, -4.59821928e-04f, -5.06946486e-04f, -5.52847863e-04f, -5.97397068e-04f, -6.40454770e-04f, + -6.81765968e-04f, -7.21210131e-04f, -7.58634477e-04f, -7.93939572e-04f, -8.26964876e-04f, -8.57585335e-04f, + -8.85733438e-04f, -9.11351007e-04f, -9.34300512e-04f, -9.54617442e-04f, -9.72159416e-04f, -9.87012089e-04f, + -9.99095133e-04f, -1.00846242e-03f, -1.01506022e-03f, -1.01897105e-03f, -1.02021427e-03f, -1.01887259e-03f, + -1.01497557e-03f, -1.00861358e-03f, -9.99877741e-04f, -9.88823136e-04f, -9.75617693e-04f, -9.60303769e-04f, + -9.43035535e-04f, -9.23922797e-04f, -9.03105429e-04f, -8.80708716e-04f, -8.56853281e-04f, -8.31685264e-04f, + -8.05348207e-04f, -7.77961627e-04f, -7.49713086e-04f, -7.20674604e-04f, -6.91032783e-04f, -6.60888020e-04f, + -6.30372917e-04f, -5.99673349e-04f, -5.68830563e-04f, -5.38013304e-04f, -5.07353303e-04f, -4.76915043e-04f, + -4.46832926e-04f, -4.17179291e-04f, -3.88083307e-04f, -3.59575024e-04f, -3.31820735e-04f, -3.04804303e-04f, + -2.78616041e-04f, -2.53335964e-04f, -2.28986996e-04f, -2.05619529e-04f, -1.83318449e-04f, -1.61979425e-04f, + -1.41791423e-04f, -1.22648816e-04f, -1.04625498e-04f, -8.77122910e-05f, -7.18653457e-05f, -5.71787106e-05f, + -4.34807639e-05f, -3.09618857e-05f, -1.94074401e-05f, -8.88017971e-06f, 6.09625220e-07f, 9.14020334e-06f, + 1.67805558e-05f, 2.35369965e-05f, 2.94278194e-05f, 3.45049751e-05f, 3.88373828e-05f, 4.24291966e-05f, + 4.53445665e-05f, 4.76965834e-05f, 4.93395567e-05f, 5.05392111e-05f, 5.12257065e-05f, 5.14579340e-05f, + 5.12651750e-05f, 5.07312551e-05f, 4.98486765e-05f, 4.87082573e-05f, 4.73439631e-05f, 4.56740817e-05f, + 4.38653618e-05f, 4.19399075e-05f, 3.99125668e-05f, 3.77616021e-05f, 3.56135997e-05f, 3.33554815e-05f, + 3.11656899e-05f, 2.89038150e-05f, 2.67281634e-05f, 2.46192762e-05f, 2.24899205e-05f, 2.04698700e-05f, + 1.84927655e-05f, 1.66762886e-05f, 1.49393771e-05f, 1.32258081e-05f, 1.16985586e-05f, 1.01874391e-05f, + 8.99882100e-06f, 7.61267073e-06f, 6.57702907e-06f, 5.59829210e-06f, 4.27698546e-06f, 1.03248674e-05f, }; From b254353b38272344afaf16a1c8f5135747939483 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 07:09:41 -0700 Subject: [PATCH 166/418] Update collectHifiStats.js Clears the current batch after we send it to the endpoint. --- examples/example/misc/collectHifiStats.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/example/misc/collectHifiStats.js b/examples/example/misc/collectHifiStats.js index 3902622217..8501fbb057 100644 --- a/examples/example/misc/collectHifiStats.js +++ b/examples/example/misc/collectHifiStats.js @@ -90,4 +90,5 @@ function sendBatchToEndpoint(batch) { var req = new XMLHttpRequest(); req.open("POST", ENDPOINT_URL, false); req.send(JSON.stringify(batch)); -} \ No newline at end of file + batch = []; +} From 4c1263045873ddbb49496b65bdc2042c8086a91c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sat, 26 Sep 2015 09:09:39 -0700 Subject: [PATCH 167/418] Removed a stray reference to SOXR --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b91fac2538..db0e82f64d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,7 +181,6 @@ setup_externals_binary_dir() option(GET_BULLET "Get Bullet library automatically as external project" 1) option(GET_GLM "Get GLM library automatically as external project" 1) option(GET_GVERB "Get Gverb library automatically as external project" 1) -option(GET_SOXR "Get Soxr library automatically as external project" 1) option(GET_TBB "Get Threading Building Blocks library automatically as external project" 1) option(GET_LIBOVR "Get LibOVR library automatically as external project" 1) option(GET_VHACD "Get V-HACD library automatically as external project" 1) From 57aca0c4187b736a454c640bdf2b51a38c1cdfee Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:18:22 -0700 Subject: [PATCH 168/418] New way to do two-way bindings between dynamically created GUI and in-world object properties. Uses partcile system properties, specifically. --- examples/particle_explorer/dat.gui.min.js | 95 + examples/particle_explorer/index.html | 34 + examples/particle_explorer/main.js | 170 ++ examples/particle_explorer/old.html | 1607 +++++++++++++++++ .../particle_explorer/particleExplorer.js | 173 ++ examples/particle_explorer/underscore-min.js | 6 + 6 files changed, 2085 insertions(+) create mode 100644 examples/particle_explorer/dat.gui.min.js create mode 100644 examples/particle_explorer/index.html create mode 100644 examples/particle_explorer/main.js create mode 100644 examples/particle_explorer/old.html create mode 100644 examples/particle_explorer/particleExplorer.js create mode 100644 examples/particle_explorer/underscore-min.js diff --git a/examples/particle_explorer/dat.gui.min.js b/examples/particle_explorer/dat.gui.min.js new file mode 100644 index 0000000000..8ea141a966 --- /dev/null +++ b/examples/particle_explorer/dat.gui.min.js @@ -0,0 +1,95 @@ +/** + * dat-gui JavaScript Controller Library + * http://code.google.com/p/dat-gui + * + * Copyright 2011 Data Arts Team, Google Creative Lab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(f,a){a=a||document;var d=a.createElement("link");d.type="text/css";d.rel="stylesheet";d.href=f;a.getElementsByTagName("head")[0].appendChild(d)},inject:function(f,a){a=a||document;var d=document.createElement("style");d.type="text/css";d.innerHTML=f;a.getElementsByTagName("head")[0].appendChild(d)}}}(); +dat.utils.common=function(){var f=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(d){this.each(a.call(arguments,1),function(a){for(var c in a)this.isUndefined(a[c])||(d[c]=a[c])},this);return d},defaults:function(d){this.each(a.call(arguments,1),function(a){for(var c in a)this.isUndefined(d[c])&&(d[c]=a[c])},this);return d},compose:function(){var d=a.call(arguments);return function(){for(var e=a.call(arguments),c=d.length-1;0<=c;c--)e=[d[c].apply(this,e)];return e[0]}}, +each:function(a,e,c){if(a)if(f&&a.forEach&&a.forEach===f)a.forEach(e,c);else if(a.length===a.length+0)for(var b=0,p=a.length;bthis.__max&&(a=this.__max);void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step);return e.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__impliedStep=this.__step=a;this.__precision=d(a);return this}});return e}(dat.controllers.Controller,dat.utils.common); +dat.controllers.NumberControllerBox=function(f,a,d){var e=function(c,b,f){function q(){var a=parseFloat(n.__input.value);d.isNaN(a)||n.setValue(a)}function l(a){var b=u-a.clientY;n.setValue(n.getValue()+b*n.__impliedStep);u=a.clientY}function r(){a.unbind(window,"mousemove",l);a.unbind(window,"mouseup",r)}this.__truncationSuspended=!1;e.superclass.call(this,c,b,f);var n=this,u;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",q);a.bind(this.__input, +"blur",function(){q();n.__onFinishChange&&n.__onFinishChange.call(n,n.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",l);a.bind(window,"mouseup",r);u=b.clientY});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&(n.__truncationSuspended=!0,this.blur(),n.__truncationSuspended=!1)});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype,f.prototype,{updateDisplay:function(){var a=this.__input,b;if(this.__truncationSuspended)b= +this.getValue();else{b=this.getValue();var d=Math.pow(10,this.__precision);b=Math.round(b*d)/d}a.value=b;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); +dat.controllers.NumberControllerSlider=function(f,a,d,e,c){function b(a,b,c,e,d){return e+(a-b)/(c-b)*(d-e)}var p=function(c,e,d,f,u){function A(c){c.preventDefault();var e=a.getOffset(k.__background),d=a.getWidth(k.__background);k.setValue(b(c.clientX,e.left,e.left+d,k.__min,k.__max));return!1}function g(){a.unbind(window,"mousemove",A);a.unbind(window,"mouseup",g);k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())}p.superclass.call(this,c,e,{min:d,max:f,step:u});var k=this;this.__background= +document.createElement("div");this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",A);a.bind(window,"mouseup",g);A(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};p.superclass=f;p.useDefaultStyles=function(){d.inject(c)};e.extend(p.prototype,f.prototype,{updateDisplay:function(){var a= +(this.getValue()-this.__min)/(this.__max-this.__min);this.__foreground.style.width=100*a+"%";return p.superclass.prototype.updateDisplay.call(this)}});return p}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); +dat.controllers.FunctionController=function(f,a,d){var e=function(c,b,d){e.superclass.call(this,c,b);var f=this;this.__button=document.createElement("div");this.__button.innerHTML=void 0===d?"Fire":d;a.bind(this.__button,"click",function(a){a.preventDefault();f.fire();return!1});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};e.superclass=f;d.extend(e.prototype,f.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.getValue().call(this.object); +this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.controllers.BooleanController=function(f,a,d){var e=function(c,b){e.superclass.call(this,c,b);var d=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){d.setValue(!d.__prev)},!1);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};e.superclass=f;d.extend(e.prototype,f.prototype,{setValue:function(a){a=e.superclass.prototype.setValue.call(this,a);this.__onFinishChange&& +this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.color.toString=function(f){return function(a){if(1==a.a||f.isUndefined(a.a)){for(a=a.hex.toString(16);6>a.length;)a="0"+a;return"#"+a}return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common); +dat.color.interpret=function(f,a){var d,e,c=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:f},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:f},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); +return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:f},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:f}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3!= +a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4!=a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&& +a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){e=!1; +var b=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n', +".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", +dat.controllers.factory=function(f,a,d,e,c,b,p){return function(q,l,r,n){var u=q[l];if(p.isArray(r)||p.isObject(r))return new f(q,l,r);if(p.isNumber(u))return p.isNumber(r)&&p.isNumber(n)?new d(q,l,r,n):new a(q,l,{min:r,max:n});if(p.isString(u))return new e(q,l);if(p.isFunction(u))return new c(q,l,"");if(p.isBoolean(u))return new b(q,l)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(f,a,d){var e= +function(c,b){function d(){f.setValue(f.__input.value)}e.superclass.call(this,c,b);var f=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",d);a.bind(this.__input,"change",d);a.bind(this.__input,"blur",function(){f.__onFinishChange&&f.__onFinishChange.call(f,f.getValue())});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype, +f.prototype,{updateDisplay:function(){a.isActive(this.__input)||(this.__input.value=this.getValue());return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController, +dat.controllers.ColorController=function(f,a,d,e,c){function b(a,b,d,e){a.style.background="";c.each(l,function(c){a.style.cssText+="background: "+c+"linear-gradient("+b+", "+d+" 0%, "+e+" 100%); "})}function p(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; +a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var q=function(f,n){function u(b){v(b);a.bind(window,"mousemove",v);a.bind(window, +"mouseup",l)}function l(){a.unbind(window,"mousemove",v);a.unbind(window,"mouseup",l)}function g(){var a=e(this.value);!1!==a?(t.__color.__state=a,t.setValue(t.__color.toOriginal())):this.value=t.__color.toString()}function k(){a.unbind(window,"mousemove",w);a.unbind(window,"mouseup",k)}function v(b){b.preventDefault();var c=a.getWidth(t.__saturation_field),d=a.getOffset(t.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c;b=1-(b.clientY-d.top+document.body.scrollTop)/c;1 +b&&(b=0);1e&&(e=0);t.__color.v=b;t.__color.s=e;t.setValue(t.__color.toOriginal());return!1}function w(b){b.preventDefault();var c=a.getHeight(t.__hue_field),d=a.getOffset(t.__hue_field);b=1-(b.clientY-d.top+document.body.scrollTop)/c;1b&&(b=0);t.__color.h=360*b;t.setValue(t.__color.toOriginal());return!1}q.superclass.call(this,f,n);this.__color=new d(this.getValue());this.__temp=new d(0);var t=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,!1); +this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=document.createElement("input"); +this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){13===a.keyCode&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(b){a.addClass(this,"drag").bind(window,"mouseup",function(b){a.removeClass(t.__selector,"drag")})});var y=document.createElement("div");c.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});c.extend(this.__field_knob.style, +{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});c.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});c.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});c.extend(y.style,{width:"100%",height:"100%", +background:"none"});b(y,"top","rgba(0,0,0,0)","#000");c.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});p(this.__hue_field);c.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",u);a.bind(this.__field_knob,"mousedown",u);a.bind(this.__hue_field,"mousedown",function(b){w(b);a.bind(window, +"mousemove",w);a.bind(window,"mouseup",k)});this.__saturation_field.appendChild(y);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};q.superclass=f;c.extend(q.prototype,f.prototype,{updateDisplay:function(){var a=e(this.getValue());if(!1!==a){var f=!1; +c.each(d.COMPONENTS,function(b){if(!c.isUndefined(a[b])&&!c.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return f=!0,{}},this);f&&c.extend(this.__color.__state,a)}c.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var l=.5>this.__color.v||.5a&&(a+=1);return{h:360*a,s:c/b,v:b/255}},rgb_to_hex:function(a,d,e){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,d);return a=this.hex_with_component(a,0,e)},component_from_hex:function(a,d){return a>>8*d&255},hex_with_component:function(a,d,e){return e<<(f=8*d)|a&~(255< + + + + + + + + + +
    +
    + + \ No newline at end of file diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js new file mode 100644 index 0000000000..fc06ba345b --- /dev/null +++ b/examples/particle_explorer/main.js @@ -0,0 +1,170 @@ +// +// main.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Web app side of the App - contains GUI. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +var PI = 3.141593, + DEG_TO_RAD = PI / 180.0; + +function radiansToDegrees(radians) { + return radians * (180 / PI) +} + +// need to add '_group' to the end of properties that will need to be made part of a group on the backend +// property_subproperty_group = value +// i.e. color_red_group = 0; + +var ParticleExplorer = function() { + this.animationIsPlaying = true; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.lifetime = 3600 // 1 hour; just in case + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + +} + +//we need a way to keep track of our gui controllers +var controllers = []; +window.onload = function() { + + //instantiate our object + var particleExplorer = new ParticleExplorer(); + + //whether or not to autoplace + var gui = new dat.GUI({ + autoPlace: false + }); + + //if not autoplacing, put gui in a custom container + if (gui.autoPlace === false) { + + var customContainer = document.getElementById('my-gui-container'); + customContainer.appendChild(gui.domElement); + gui.width = 400; + + } + + //add save settings ability (try not to use localstorage) + gui.remember(particleExplorer); + + //get object keys + var particleKeys = _.keys(particleExplorer); + + //for each key... + _.each(particleKeys, function(key) { + //add this key as a controller to the gui + var controller = gui.add(particleExplorer, key); + if (key.indexOf('_group') > -1) { + controller.shouldGroup = true; + } else { + controller.shouldGroup = false; + } + + + //keep track of our controller + controllers.push(controller); + + //hook into change events for this gui controller + controller.onChange(function(value) { + // Fires on every change, drag, keypress, etc. + // writeDataToInterface(this.property, value, this.shouldGroup) + }); + + controller.onFinishChange(function(value) { + console.log('should group?', controller.shouldGroup) + // Fires when a controller loses focus. + writeDataToInterface(this.property, value, this.shouldGroup) + }); + + }); + +}; + +function writeDataToInterface(property, value, shouldGroup) { + console.log('shouldgrouppppp', shouldGroup) + var group = null; + var groupProperty = null; + var groupProperties = null; + if (shouldGroup) { + var separated = property.slice(0, property.indexOf('_group')).split("_") + group = separated[0]; + groupProperty = separated[1]; + var groupString = group.toString(); + var groupPropertyString = groupProperty.toString(); + var groupProperties = {} + groupProperties[group] = {}; + groupProperties[group][groupProperty] = value + console.log(groupProperties) + + } + + var data = { + type: "particleExplorer_update", + shouldGroup: shouldGroup, + groupProperties: groupProperties, + singleProperty: {} + } + + data['singleProperty'][property] = value + + var stringifiedData = JSON.stringify(data) + + console.log('stringifiedData', stringifiedData) + if (typeof EventBridge !== 'undefined') { + EventBridge.emitWebEvent( + stringifiedData + ); + } + +} \ No newline at end of file diff --git a/examples/particle_explorer/old.html b/examples/particle_explorer/old.html new file mode 100644 index 0000000000..f2d91bda70 --- /dev/null +++ b/examples/particle_explorer/old.html @@ -0,0 +1,1607 @@ + + + Properties + + + + + + + + +
    +
    +
    + +
    +
    +
    + + + +
    + +
    +
    +
    + Name +
    + +
    +
    + +
    + Locked + + + +
    + +
    + Visible + + + +
    + +
    +
    User Data
    +
    + +
    +
    + + +
    + +
    + +
    +
    Href
    +
    + +
    +
    +
    +
    Description
    +
    + +
    +
    + + +
    + +
    + +
    +
    Position
    +
    +
    X
    +
    Y
    +
    Z
    +
    + + +
    +
    +
    + +
    +
    Registration
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Dimensions
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    +
    + % +
    + + + +
    +
    + +
    +
    Voxel Volume Size
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    Surface Extractor
    +
    + +
    + +
    X-axis Texture URL
    +
    + +
    + +
    Y-axis Texture URL
    +
    + +
    + +
    Z-axis Texture URL
    +
    + +
    +
    + +
    +
    Rotation
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    + + +
    + +
    + +
    +
    Linear Velocity
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    +
    +
    Linear Damping
    +
    + +
    +
    +
    +
    Angular Velocity
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    +
    +
    Angular Damping
    +
    + +
    +
    +
    +
    Restitution
    +
    + +
    +
    +
    +
    Friction
    +
    + +
    +
    + +
    +
    Gravity
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Acceleration
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Density
    +
    + +
    +
    + +
    +
    Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    + + +
    + +
    + +
    + Ignore For Collisions + + + +
    + +
    + Collisions Will Move + + + +
    + +
    +
    Collision Sound URL
    +
    + +
    +
    + +
    +
    Lifetime
    +
    + +
    +
    + +
    +
    Script URL + + +
    +
    + +
    +
    + + +
    + +
    + +
    +
    Model URL
    +
    + +
    +
    + +
    +
    Shape Type
    +
    + +
    +
    +
    +
    Compound Shape URL
    +
    + +
    +
    +
    +
    Animation URL
    +
    + +
    +
    +
    + Animation Playing + + + +
    +
    +
    Animation FPS
    +
    + +
    +
    +
    +
    Animation Frame
    +
    + +
    +
    +
    +
    Animation Settings
    +
    + +
    +
    +
    +
    Textures
    +
    + +
    +
    +
    +
    Original Textures
    +
    + +
    +
    + + +
    + +
    + +
    +
    Source URL
    +
    + +
    +
    + + +
    + +
    + +
    +
    Max Particles
    +
    + +
    +
    +
    +
    Particle Life Span
    +
    + +
    +
    +
    +
    Particle Emission Rate
    +
    + +
    +
    +
    +
    Particle Emission Direction
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    +
    +
    Particle Emission Strength
    +
    + +
    +
    +
    +
    Particle Local Gravity
    +
    + +
    +
    +
    +
    Particle Radius
    +
    + +
    +
    + + +
    + +
    + +
    +
    Text Content
    +
    + +
    +
    +
    +
    Line Height
    +
    + +
    +
    +
    +
    Text Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Background Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    + + +
    + +
    + +
    + Spot Light + + + +
    +
    +
    Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Intensity
    +
    + +
    +
    +
    +
    Spot Light Exponent
    +
    + +
    +
    +
    +
    Spot Light Cutoff (degrees)
    +
    + +
    +
    + + +
    + +
    + +
    + Stage Sun Model Enabled + + + +
    + +
    +
    Key Light Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Key Light Intensity
    +
    + +
    +
    +
    +
    Key Light Ambient Intensity
    +
    + +
    +
    +
    +
    Key Light Direction
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    + +
    +
    Stage Latitude
    +
    + +
    +
    +
    +
    Stage Longitude
    +
    + +
    +
    +
    +
    Stage Altitude
    +
    + +
    +
    + +
    + Automatically calculate stage hour and day from location and clock. + + + +
    + +
    +
    Stage Day
    +
    + +
    +
    +
    +
    Stage Hour
    +
    + +
    +
    + +
    +
    Background Mode
    +
    + +
    +
    + + +
    + +
    + +
    +
    Skybox Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Skybox URL
    +
    + +
    +
    + + +
    + +
    + +
    +
    Atmosphere Center
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    +
    +
    +
    +
    Atmosphere Inner Radius
    +
    + +
    +
    +
    +
    Atmosphere Outer Radius
    +
    + +
    +
    +
    +
    Atmosphere Mie Scattering
    +
    + +
    +
    +
    +
    Atmosphere Rayleigh Scattering
    +
    + +
    +
    +
    +
    Atmosphere Scattering Wavelenghts
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    + + \ No newline at end of file diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js new file mode 100644 index 0000000000..a0116a0f34 --- /dev/null +++ b/examples/particle_explorer/particleExplorer.js @@ -0,0 +1,173 @@ +// +// particleExplorer.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Interface side of the App. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// +var boxPoint, + spawnPoint, + animation = { + fps: 30, + frameIndex: 0, + running: true, + firstFrame: 0, + lastFrame: 30, + loop: true + }; + + +var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); +boxPoint = Vec3.sum(boxPoint, { + x: 0.0, + y: -0.5, + z: 0.0 +}); +spawnPoint = Vec3.sum(boxPoint, { + x: 0.0, + y: 1.0, + z: 0.0 +}); + +var PI = 3.141593, + DEG_TO_RAD = PI / 180.0; + +BlankBox = function() { + this.animationIsPlaying = true; + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + // + this.type = "ParticleEffect"; + this.name = "ParticlesTest Emitter"; + this.position = spawnPoint; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.animationSettings = animation; + this.lifetime = 3600 // 1 hour; just in case +} + +var blankBox = new BlankBox(); + +var box = Entities.addEntity({ + type: "Box", + name: "ParticlesTest Box", + position: boxPoint, + rotation: { + x: -0.7071067690849304, + y: 0, + z: 0, + w: 0.7071067690849304 + }, + dimensions: { + x: 0.3, + y: 0.3, + z: 0.3 + }, + color: { + red: 128, + green: 128, + blue: 128 + }, + lifetime: 3600, // 1 hour; just in case + visible: true +}); + +var testParticles = Entities.addEntity(blankBox); + +SettingsWindow = function() { + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + print('INIT testParticles' + testParticles) + }; + this.onWebEventReceived = function(data) { + print('DATA ' + data) + + + var _data = JSON.parse(data) + if (_data.type !== 'particleExplorer_update') { + return; + } + if (_data.shouldGroup === true) { + print('USE GROUP PROPERTIES') + editEntity(_data.groupProperties) + return; + } else { + print('USE A SINGLE PROPERTY') + editEntity(_data.singleProperty) + + } + + + }; + +} + + +function editEntity(properties) { + // print('TEST PARTICLES??' + testParticles) + print('PROPS' + JSON.stringify(properties)); + Entities.editEntity(testParticles, properties); + var currentProperties = Entities.getEntityProperties(testParticles) + print('CURRENT PROPS', JSON.stringify(currentProperties)) +} + + +var settingsWindow = new SettingsWindow(); +settingsWindow.init(); + +function cleanup() { + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); +} +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/particle_explorer/underscore-min.js b/examples/particle_explorer/underscore-min.js new file mode 100644 index 0000000000..f01025b7bc --- /dev/null +++ b/examples/particle_explorer/underscore-min.js @@ -0,0 +1,6 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); +//# sourceMappingURL=underscore-min.map \ No newline at end of file From d8e7cd89ada48e862d4b19408ffd5894912a9132 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:27:58 -0700 Subject: [PATCH 169/418] Cleanup, comments --- examples/particle_explorer/main.js | 2 +- examples/particle_explorer/particleExplorer.js | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index fc06ba345b..6509a6e865 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -122,7 +122,7 @@ window.onload = function() { }); controller.onFinishChange(function(value) { - console.log('should group?', controller.shouldGroup) + // console.log('should group?', controller.shouldGroup) // Fires when a controller loses focus. writeDataToInterface(this.property, value, this.shouldGroup) }); diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index a0116a0f34..a39b3e0307 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -131,19 +131,17 @@ SettingsWindow = function() { print('INIT testParticles' + testParticles) }; this.onWebEventReceived = function(data) { - print('DATA ' + data) - - + // print('DATA ' + data) var _data = JSON.parse(data) if (_data.type !== 'particleExplorer_update') { return; } if (_data.shouldGroup === true) { - print('USE GROUP PROPERTIES') + // print('USE GROUP PROPERTIES') editEntity(_data.groupProperties) return; } else { - print('USE A SINGLE PROPERTY') + // print('USE A SINGLE PROPERTY') editEntity(_data.singleProperty) } @@ -155,11 +153,9 @@ SettingsWindow = function() { function editEntity(properties) { - // print('TEST PARTICLES??' + testParticles) - print('PROPS' + JSON.stringify(properties)); Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } From a0b3bd91a3076d5bcbdfb6b0b626f55e21fee804 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:40:31 -0700 Subject: [PATCH 170/418] cleanup logging --- examples/particle_explorer/main.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 6509a6e865..057932f309 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -132,7 +132,6 @@ window.onload = function() { }; function writeDataToInterface(property, value, shouldGroup) { - console.log('shouldgrouppppp', shouldGroup) var group = null; var groupProperty = null; var groupProperties = null; @@ -145,7 +144,7 @@ function writeDataToInterface(property, value, shouldGroup) { var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value - console.log(groupProperties) + // console.log(groupProperties) } @@ -160,7 +159,6 @@ function writeDataToInterface(property, value, shouldGroup) { var stringifiedData = JSON.stringify(data) - console.log('stringifiedData', stringifiedData) if (typeof EventBridge !== 'undefined') { EventBridge.emitWebEvent( stringifiedData From 50dd8eba4586c9494efdd5bfa31ba1793daa246a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Sep 2015 08:23:50 -0700 Subject: [PATCH 171/418] Relay joint translations across network. Apply animation's root-joint translation to avatar. --- .../src/avatars/ScriptableAvatar.cpp | 14 +- interface/src/avatar/Avatar.cpp | 17 +- interface/src/avatar/Avatar.h | 1 + interface/src/avatar/MyAvatar.cpp | 37 ++- interface/src/avatar/MyAvatar.h | 5 +- interface/src/avatar/SkeletonModel.cpp | 1 + libraries/animation/src/AnimClip.cpp | 8 +- .../animation/src/AnimInverseKinematics.cpp | 3 + libraries/animation/src/AnimManipulator.cpp | 2 + libraries/animation/src/AnimationHandle.cpp | 11 + libraries/animation/src/AvatarRig.cpp | 27 +- libraries/animation/src/AvatarRig.h | 4 + libraries/animation/src/EntityRig.cpp | 14 + libraries/animation/src/EntityRig.h | 1 + libraries/animation/src/JointState.cpp | 32 ++- libraries/animation/src/JointState.h | 14 +- libraries/animation/src/Rig.cpp | 37 ++- libraries/animation/src/Rig.h | 12 +- libraries/avatars/src/AvatarData.cpp | 264 ++++++++++++++++-- libraries/avatars/src/AvatarData.h | 15 +- libraries/avatars/src/Player.cpp | 11 +- libraries/avatars/src/Recording.cpp | 14 +- libraries/avatars/src/Recording.h | 5 +- .../src/RenderableModelEntityItem.cpp | 9 +- libraries/entities/src/ModelEntityItem.cpp | 33 ++- libraries/entities/src/ModelEntityItem.h | 5 +- libraries/fbx/src/FBXReader.cpp | 39 ++- libraries/fbx/src/FBXReader.h | 2 +- .../networking/src/udt/PacketHeaders.cpp | 3 + libraries/render-utils/src/Model.cpp | 16 +- libraries/render-utils/src/Model.h | 5 +- libraries/shared/src/GLMHelpers.cpp | 2 + libraries/shared/src/GLMHelpers.h | 6 + 33 files changed, 585 insertions(+), 84 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 0b7af01c94..36a527009e 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -77,7 +77,19 @@ void ScriptableAvatar::update(float deltatime) { int mapping = animationJoints.indexOf(modelJoints[i]); if (mapping != -1 && !_maskedJoints.contains(modelJoints[i])) { JointData& data = _jointData[i]; - data.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + + auto newRotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + auto newTranslation = floorFrame.translations.at(i) * (1.0f - frameFraction) + + ceilFrame.translations.at(i) * frameFraction; + + if (data.rotation != newRotation) { + data.rotation = newRotation; + data.rotationSet = true; + } + if (data.translation != newTranslation) { + data.translation = newTranslation; + data.translationSet = true; + } } } } else { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0d1c3b8a20..faf4bffeba 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -202,11 +202,14 @@ void Avatar::simulate(float deltaTime) { PerformanceTimer perfTimer("skeleton"); for (int i = 0; i < _jointData.size(); i++) { const JointData& data = _jointData.at(i); - _skeletonModel.setJointState(i, true, data.rotation); + _skeletonModel.setJointRotation(i, data.rotationSet, data.rotation, 1.0f); + _skeletonModel.setJointTranslation(i, data.translationSet, data.translation, 1.0f); } - _skeletonModel.simulate(deltaTime, _hasNewJointRotations); + + _skeletonModel.simulate(deltaTime, _hasNewJointRotations || _hasNewJointTranslations); simulateAttachments(deltaTime); _hasNewJointRotations = false; + _hasNewJointTranslations = false; } { PerformanceTimer perfTimer("head"); @@ -879,6 +882,16 @@ glm::quat Avatar::getJointRotation(int index) const { return rotation; } +glm::vec3 Avatar::getJointTranslation(int index) const { + if (QThread::currentThread() != thread()) { + return AvatarData::getJointTranslation(index); + } + glm::vec3 translation; + _skeletonModel.getJointTranslation(index, translation); + return translation; +} + + int Avatar::getJointIndex(const QString& name) const { if (QThread::currentThread() != thread()) { int result; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 6cfbf939a2..5ff3f37ef5 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -115,6 +115,7 @@ public: virtual QVector getJointRotations() const; virtual glm::quat getJointRotation(int index) const; + virtual glm::vec3 getJointTranslation(int index) const; virtual int getJointIndex(const QString& name) const; virtual QStringList getJointNames() const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4cf1b69ce4..e6013638c8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -239,9 +239,11 @@ void MyAvatar::simulate(float deltaTime) { PerformanceTimer perfTimer("joints"); // copy out the skeleton joints from the model _jointData.resize(_rig->getJointStateCount()); + for (int i = 0; i < _jointData.size(); i++) { JointData& data = _jointData[i]; - _rig->getJointStateRotation(i, data.rotation); + data.rotationSet |= _rig->getJointStateRotation(i, data.rotation); + data.translationSet |= _rig->getJointStateTranslation(i, data.translation); } } @@ -1083,21 +1085,43 @@ void MyAvatar::setJointRotations(QVector jointRotations) { int numStates = glm::min(_skeletonModel.getJointStateCount(), jointRotations.size()); for (int i = 0; i < numStates; ++i) { // HACK: ATM only Recorder calls setJointRotations() so we hardcode its priority here - _skeletonModel.setJointState(i, true, jointRotations[i], RECORDER_PRIORITY); + _skeletonModel.setJointRotation(i, true, jointRotations[i], RECORDER_PRIORITY); } } -void MyAvatar::setJointData(int index, const glm::quat& rotation) { +void MyAvatar::setJointTranslations(QVector jointTranslations) { + int numStates = glm::min(_skeletonModel.getJointStateCount(), jointTranslations.size()); + for (int i = 0; i < numStates; ++i) { + // HACK: ATM only Recorder calls setJointTranslations() so we hardcode its priority here + _skeletonModel.setJointTranslation(i, true, jointTranslations[i], RECORDER_PRIORITY); + } +} + +void MyAvatar::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) { if (QThread::currentThread() == thread()) { // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority - _rig->setJointState(index, true, rotation, SCRIPT_PRIORITY); + _rig->setJointState(index, true, rotation, translation, SCRIPT_PRIORITY); + } +} + +void MyAvatar::setJointRotation(int index, const glm::quat& rotation) { + if (QThread::currentThread() == thread()) { + // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority + _rig->setJointRotation(index, true, rotation, SCRIPT_PRIORITY); + } +} + +void MyAvatar::setJointTranslation(int index, const glm::vec3& translation) { + if (QThread::currentThread() == thread()) { + // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority + _rig->setJointTranslation(index, true, translation, SCRIPT_PRIORITY); } } void MyAvatar::clearJointData(int index) { if (QThread::currentThread() == thread()) { // HACK: ATM only JS scripts call clearJointData() on MyAvatar so we hardcode the priority - _rig->setJointState(index, false, glm::quat(), 0.0f); + _rig->setJointState(index, false, glm::quat(), glm::vec3(), 0.0f); _rig->clearJointAnimationPriority(index); } } @@ -1396,7 +1420,10 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { AnimPose pose = _debugDrawSkeleton->getRelativeBindPose(i); glm::quat jointRot; _rig->getJointRotationInConstrainedFrame(i, jointRot); + glm::vec3 jointTrans; + _rig->getJointTranslation(i, jointTrans); pose.rot = pose.rot * jointRot; + pose.trans = jointTrans; poses.push_back(pose); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c1a6ada751..6ee42778c8 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -139,7 +139,10 @@ public: void clearLookAtTargetAvatar(); virtual void setJointRotations(QVector jointRotations); - virtual void setJointData(int index, const glm::quat& rotation); + virtual void setJointTranslations(QVector jointTranslations); + virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation); + virtual void setJointRotation(int index, const glm::quat& rotation); + virtual void setJointTranslation(int index, const glm::vec3& translation); virtual void clearJointData(int index); virtual void clearJointsData(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 703f3983ee..9cffe5956f 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -648,6 +648,7 @@ void SkeletonModel::computeBoundingShape() { // RECOVER FROM BOUNINDG SHAPE HACK: now that we're all done, restore the default pose for (int i = 0; i < numStates; i++) { _rig->restoreJointRotation(i, 1.0f, 1.0f); + _rig->restoreJointTranslation(i, 1.0f, 1.0f); } } diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 23aa884933..f33c958fa8 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -147,8 +147,14 @@ void AnimClip::copyFromNetworkAnim() { for (int j = 0; j < animJointCount; j++) { int k = jointMap[j]; if (k >= 0 && k < skeletonJointCount) { - // currently FBX animations only have rotation. _anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j]; + + // TODO -- why does applying all the joint translations make a mutant? + if (animJoints[j].parentIndex == -1) { + _anim[i][k].trans = geom.animationFrames[i].translations[j] * extractScale(geom.offset); + } else { + _anim[i][k].trans = _skeleton->getRelativeBindPose(k).trans; + } } } } diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index de226092f1..037db8747c 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -322,9 +322,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar std::map::iterator constraintItr = _constraints.begin(); while (constraintItr != _constraints.end()) { int index = constraintItr->first; + glm::quat rotation = _relativePoses[index].rot; constraintItr->second->apply(rotation); _relativePoses[index].rot = rotation; + ++constraintItr; } } else { @@ -354,6 +356,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } else { _relativePoses[i].rot = underPoses[i].rot; } + _relativePoses[i].trans = underPoses[i].trans; } } return evaluate(animVars, dt, triggersOut); diff --git a/libraries/animation/src/AnimManipulator.cpp b/libraries/animation/src/AnimManipulator.cpp index 8b9089f450..6ab4017aa3 100644 --- a/libraries/animation/src/AnimManipulator.cpp +++ b/libraries/animation/src/AnimManipulator.cpp @@ -55,6 +55,7 @@ const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, floa defaultRelPose = underPoses[jointVar.jointIndex]; defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); + defaultAbsPose.trans = animVars.lookup(jointVar.var, defaultAbsPose.trans); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose. int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex); @@ -68,6 +69,7 @@ const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, floa defaultRelPose = AnimPose::identity; defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); + defaultAbsPose.trans = animVars.lookup(jointVar.var, defaultAbsPose.trans); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose // here we use the bind pose diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index f2d12b398e..a6ac9c1f97 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -173,6 +173,7 @@ void AnimationHandle::applyFrame(float frameIndex) { const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(frameIndex) % frameCount); const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at((int)glm::ceil(frameIndex) % frameCount); float frameFraction = glm::fract(frameIndex); + for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { // allow missing bones @@ -183,6 +184,15 @@ void AnimationHandle::applyFrame(float frameIndex) { _priority, false, _mix); + + // This isn't working. + // glm::vec3 floorTranslationPart = floorFrame.translations.at(i) * (1.0f - frameFraction); + // glm::vec3 ceilTranslationPart = ceilFrame.translations.at(i) * frameFraction; + // glm::vec3 floorCeilFraction = floorTranslationPart + ceilTranslationPart; + // glm::vec3 defaultTrans = _rig->getJointDefaultTranslationInConstrainedFrame(i); + // glm::vec3 mixedTranslation = floorCeilFraction * (1.0f - _mix) + defaultTrans * _mix; + // _rig->setJointTranslation(mapping, true, mixedTranslation, _priority); + } } } @@ -203,6 +213,7 @@ void AnimationHandle::restoreJoints() { int mapping = _jointMappings.at(i); if (mapping != -1) { _rig->restoreJointRotation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); + _rig->restoreJointTranslation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); } } } diff --git a/libraries/animation/src/AvatarRig.cpp b/libraries/animation/src/AvatarRig.cpp index 0727d0956d..4dbf5207b1 100644 --- a/libraries/animation/src/AvatarRig.cpp +++ b/libraries/animation/src/AvatarRig.cpp @@ -20,9 +20,7 @@ void AvatarRig::updateJointState(int index, glm::mat4 rootTransform) { // compute model transforms if (index == _rootJointIndex) { - // we always zero-out the translation part of an avatar's root join-transform. state.computeTransform(rootTransform); - clearJointTransformTranslation(index); } else { // guard against out-of-bounds access to _jointStates int parentIndex = state.getParentIndex(); @@ -97,3 +95,28 @@ void AvatarRig::setHandPosition(int jointIndex, shoulderRotation, priority); setJointRotationInBindFrame(jointIndex, rotation, priority); } + +void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setTranslation(translation, priority); + } else { + state.restoreTranslation(1.0f, priority); + } + } +} + + +void AvatarRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setRotationInConstrainedFrame(rotation, priority); + state.setTranslation(translation, priority); + } else { + state.restoreRotation(1.0f, priority); + state.restoreTranslation(1.0f, priority); + } + } +} diff --git a/libraries/animation/src/AvatarRig.h b/libraries/animation/src/AvatarRig.h index f137e89939..f45c2951e9 100644 --- a/libraries/animation/src/AvatarRig.h +++ b/libraries/animation/src/AvatarRig.h @@ -24,6 +24,10 @@ class AvatarRig : public Rig { virtual void updateJointState(int index, glm::mat4 rootTransform); virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, float scale, float priority); + virtual void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; + + #endif // hifi_AvatarRig_h diff --git a/libraries/animation/src/EntityRig.cpp b/libraries/animation/src/EntityRig.cpp index e65407116b..8748214734 100644 --- a/libraries/animation/src/EntityRig.cpp +++ b/libraries/animation/src/EntityRig.cpp @@ -27,3 +27,17 @@ void EntityRig::updateJointState(int index, glm::mat4 rootTransform) { } } } + + +void EntityRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setRotationInConstrainedFrame(rotation, priority); + // state.setTranslation(translation, priority); + } else { + state.restoreRotation(1.0f, priority); + // state.restoreTranslation(1.0f, priority); + } + } +} diff --git a/libraries/animation/src/EntityRig.h b/libraries/animation/src/EntityRig.h index b36ffb9874..17486bad78 100644 --- a/libraries/animation/src/EntityRig.h +++ b/libraries/animation/src/EntityRig.h @@ -24,6 +24,7 @@ class EntityRig : public Rig { virtual void updateJointState(int index, glm::mat4 rootTransform); virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, float scale, float priority) {} + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; #endif // hifi_EntityRig_h diff --git a/libraries/animation/src/JointState.cpp b/libraries/animation/src/JointState.cpp index 9597a46726..935319b489 100644 --- a/libraries/animation/src/JointState.cpp +++ b/libraries/animation/src/JointState.cpp @@ -43,6 +43,7 @@ void JointState::copyState(const JointState& other) { _isFree = other._isFree; _parentIndex = other._parentIndex; _defaultRotation = other._defaultRotation; + _defaultTranslation = other._defaultTranslation; _inverseDefaultRotation = other._inverseDefaultRotation; _translation = other._translation; _rotationMin = other._rotationMin; @@ -60,6 +61,7 @@ JointState::JointState(const FBXJoint& joint) { _parentIndex = joint.parentIndex; _translation = joint.translation; _defaultRotation = joint.rotation; + _defaultTranslation = _translation; _inverseDefaultRotation = joint.inverseDefaultRotation; _rotationMin = joint.rotationMin; _rotationMax = joint.rotationMax; @@ -92,6 +94,9 @@ glm::quat JointState::getRotation() const { } void JointState::initTransform(const glm::mat4& parentTransform) { + + _unitsScale = extractScale(parentTransform); + computeTransform(parentTransform); _positionInParentFrame = glm::inverse(extractRotation(parentTransform)) * (extractTranslation(_transform) - extractTranslation(parentTransform)); _distanceToParent = glm::length(_positionInParentFrame); @@ -101,11 +106,11 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT if (!parentTransformChanged && !_transformChanged) { return; } - + glm::quat rotationInParentFrame = _preRotation * _rotationInConstrainedFrame * _postRotation; glm::mat4 transformInParentFrame = _preTransform * glm::mat4_cast(rotationInParentFrame) * _postTransform; glm::mat4 newTransform = parentTransform * glm::translate(_translation) * transformInParentFrame; - + if (newTransform != _transform) { _transform = newTransform; _transformChanged = true; @@ -139,6 +144,13 @@ void JointState::restoreRotation(float fraction, float priority) { } } +void JointState::restoreTranslation(float fraction, float priority) { + if (priority == _animationPriority || _animationPriority == 0.0f) { + _translation = _translation * (1.0f - fraction) + _defaultTranslation * fraction; + _animationPriority = 0.0f; + } +} + void JointState::setRotationInBindFrame(const glm::quat& rotation, float priority, bool constrain) { // rotation is from bind- to model-frame if (priority >= _animationPriority) { @@ -245,6 +257,14 @@ void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float p } } +void JointState::setTranslation(const glm::vec3& translation, float priority) { + if (priority >= _animationPriority || _animationPriority == 0.0f) { + _translation = translation / _unitsScale; + _transformChanged = true; + _animationPriority = priority; + } +} + void JointState::setRotationInConstrainedFrameInternal(const glm::quat& targetRotation) { if (_rotationInConstrainedFrame != targetRotation) { glm::quat parentRotation = computeParentRotation(); @@ -269,13 +289,17 @@ bool JointState::rotationIsDefault(const glm::quat& rotation, float tolerance) c glm::abs(rotation.w - defaultRotation.w) < tolerance; } +bool JointState::translationIsDefault(const glm::vec3& translation, float tolerance) const { + return glm::distance(_defaultTranslation, translation * _unitsScale) < tolerance; +} + glm::quat JointState::getDefaultRotationInParentFrame() const { // NOTE: the result is constant and could be cached return _preRotation * _defaultRotation * _postRotation; } -const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { - return _translation; +glm::vec3 JointState::getDefaultTranslationInConstrainedFrame() const { + return _defaultTranslation * _unitsScale; } void JointState::slaveVisibleTransform() { diff --git a/libraries/animation/src/JointState.h b/libraries/animation/src/JointState.h index 07ed010104..d11f98cdd6 100644 --- a/libraries/animation/src/JointState.h +++ b/libraries/animation/src/JointState.h @@ -77,6 +77,8 @@ public: /// \param priority priority level of this animation blend void restoreRotation(float fraction, float priority); + void restoreTranslation(float fraction, float priority); + /// \param rotation is from bind- to model-frame /// computes and sets new _rotationInConstrainedFrame /// NOTE: the JointState's model-frame transform/rotation are NOT updated! @@ -88,14 +90,18 @@ public: void setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority, bool constrain); void setRotationInConstrainedFrame(glm::quat targetRotation, float priority, bool constrain = false, float mix = 1.0f); + + void setTranslation(const glm::vec3& translation, float priority); + void setVisibleRotationInConstrainedFrame(const glm::quat& targetRotation); const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; } const glm::quat& getVisibleRotationInConstrainedFrame() const { return _visibleRotationInConstrainedFrame; } bool rotationIsDefault(const glm::quat& rotation, float tolerance = EPSILON) const; + bool translationIsDefault(const glm::vec3& translation, float tolerance = EPSILON) const; glm::quat getDefaultRotationInParentFrame() const; - const glm::vec3& getDefaultTranslationInConstrainedFrame() const; + glm::vec3 getDefaultTranslationInConstrainedFrame() const; void clearTransformTranslation(); @@ -110,12 +116,13 @@ public: void setTransform(const glm::mat4& transform) { _transform = transform; } void setVisibleTransform(const glm::mat4& transform) { _visibleTransform = transform; } - const glm::vec3& getTranslation() const { return _translation; } + glm::vec3 getTranslation() const { return _translation * _unitsScale; } const glm::mat4& getPreTransform() const { return _preTransform; } const glm::mat4& getPostTransform() const { return _postTransform; } const glm::quat& getPreRotation() const { return _preRotation; } const glm::quat& getPostRotation() const { return _postRotation; } const glm::quat& getDefaultRotation() const { return _defaultRotation; } + glm::vec3 getDefaultTranslation() const { return _defaultTranslation * _unitsScale; } const glm::quat& getInverseDefaultRotation() const { return _inverseDefaultRotation; } const QString& getName() const { return _name; } bool getIsFree() const { return _isFree; } @@ -144,6 +151,7 @@ private: glm::quat _defaultRotation; // Not necessarilly bind rotation. See FBXJoint transform/bindTransform glm::quat _inverseDefaultRotation; + glm::vec3 _defaultTranslation; glm::vec3 _translation; QString _name; int _parentIndex; @@ -155,6 +163,8 @@ private: glm::mat4 _preTransform; glm::mat4 _postTransform; glm::quat _inverseBindRotation; + + glm::vec3 _unitsScale{1.0f, 1.0f, 1.0f}; }; #endif // hifi_JointState_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 1874939b3d..eaad5e6bb6 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -270,6 +270,7 @@ void Rig::reset(const QVector& fbxJoints) { } for (int i = 0; i < _jointStates.size(); i++) { _jointStates[i].setRotationInConstrainedFrame(fbxJoints.at(i).rotation, 0.0f); + _jointStates[i].setTranslation(fbxJoints.at(i).translation, 0.0f); } } @@ -289,6 +290,16 @@ bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { return !state.rotationIsDefault(rotation); } +bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { + if (index == -1 || index >= _jointStates.size()) { + return false; + } + const JointState& state = _jointStates.at(index); + translation = state.getTranslation(); + return !state.translationIsDefault(translation); +} + + bool Rig::getVisibleJointState(int index, glm::quat& rotation) const { if (index == -1 || index >= _jointStates.size()) { return false; @@ -302,6 +313,7 @@ void Rig::clearJointState(int index) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; state.setRotationInConstrainedFrame(glm::quat(), 0.0f); + state.setTranslation(state.getDefaultTranslationInConstrainedFrame(), 0.0f); } } @@ -328,7 +340,7 @@ void Rig::setJointAnimatinoPriority(int index, float newPriority) { } } -void Rig::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { +void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, float priority) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; if (valid) { @@ -345,6 +357,12 @@ void Rig::restoreJointRotation(int index, float fraction, float priority) { } } +void Rig::restoreJointTranslation(int index, float fraction, float priority) { + if (index != -1 && index < _jointStates.size()) { + _jointStates[index].restoreTranslation(fraction, priority); + } +} + bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { @@ -380,6 +398,14 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { return true; } +bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { + if (jointIndex == -1 || jointIndex >= _jointStates.size()) { + return false; + } + translation = _jointStates[jointIndex].getTranslation(); + return true; +} + bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; @@ -590,7 +616,13 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { // copy poses into jointStates const float PRIORITY = 1.0f; for (size_t i = 0; i < poses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false); + setJointRotationInConstrainedFrame((int)i, + glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, + PRIORITY, + false); + + JointState& state = _jointStates[i]; + setJointTranslation((int)i, true, poses[i].trans, PRIORITY); } } else { @@ -866,6 +898,7 @@ bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, c foreach (int index, freeLineage) { JointState& state = _jointStates[index]; state.restoreRotation(fraction, priority); + state.restoreTranslation(fraction, priority); } return true; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 90082ca38b..f31d030910 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -123,12 +123,13 @@ public: int rightShoulderJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; int getJointStateCount() const { return _jointStates.size(); } - int indexOfJoint(const QString& jointName) ; + int indexOfJoint(const QString& jointName); void initJointTransforms(glm::mat4 rootTransform); void clearJointTransformTranslation(int jointIndex); void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; + bool getJointStateTranslation(int index, glm::vec3& translation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority); JointState getJointState(int jointIndex) const; // XXX bool getVisibleJointState(int index, glm::quat& rotation) const; @@ -137,14 +138,21 @@ public: void clearJointAnimationPriority(int index); float getJointAnimatinoPriority(int index); void setJointAnimatinoPriority(int index, float newPriority); - void setJointState(int index, bool valid, const glm::quat& rotation, float priority); + + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, + float priority) = 0; + virtual void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {} + void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority); + void restoreJointRotation(int index, float fraction, float priority); + void restoreJointTranslation(int index, float fraction, float priority); bool getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const; bool getJointPosition(int jointIndex, glm::vec3& position) const; bool getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const glm::quat& rotation) const; bool getJointRotation(int jointIndex, glm::quat& rotation) const; + bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 104b592c1a..3ef53e245b 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -49,6 +49,7 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _forceFaceTrackerConnected(false), _hasNewJointRotations(true), + _hasNewJointTranslations(true), _headData(NULL), _handData(NULL), _faceModelURL("http://invalid.com"), @@ -278,12 +279,16 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { // pupil dilation destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f); - // joint data + // joint rotation data *destinationBuffer++ = _jointData.size(); unsigned char* validityPosition = destinationBuffer; unsigned char validity = 0; int validityBit = 0; + #ifdef WANT_DEBUG + int rotationSentCount = 0; + #endif + _lastSentJointData.resize(_jointData.size()); for (int i=0; i < _jointData.size(); i++) { @@ -292,7 +297,12 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { if (sendAll || !cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { - validity |= (1 << validityBit); + if (data.rotationSet) { + validity |= (1 << validityBit); + #ifdef WANT_DEBUG + rotationSentCount++; + #endif + } } } if (++validityBit == BITS_IN_BYTE) { @@ -317,6 +327,73 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } + + // joint translation data + validityPosition = destinationBuffer; + validity = 0; + validityBit = 0; + + #ifdef WANT_DEBUG + int translationSentCount = 0; + #endif + + float maxTranslationDimension = 0.0; + for (int i=0; i < _jointData.size(); i++) { + const JointData& data = _jointData.at(i); + if (sendAll || _lastSentJointData[i].translation != data.translation) { + if (sendAll || + !cullSmallChanges || + glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { + if (data.translationSet) { + validity |= (1 << validityBit); + #ifdef WANT_DEBUG + translationSentCount++; + #endif + maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); + } + } + } + if (++validityBit == BITS_IN_BYTE) { + *destinationBuffer++ = validity; + validityBit = validity = 0; + } + } + + + if (validityBit != 0) { + *destinationBuffer++ = validity; + } + + // TODO -- automatically pick translationCompressionRadix + int translationCompressionRadix = 12; + + *destinationBuffer++ = translationCompressionRadix; + + validityBit = 0; + validity = *validityPosition++; + for (int i = 0; i < _jointData.size(); i ++) { + const JointData& data = _jointData[ i ]; + if (validity & (1 << validityBit)) { + destinationBuffer += + packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, translationCompressionRadix); + } + if (++validityBit == BITS_IN_BYTE) { + validityBit = 0; + validity = *validityPosition++; + } + } + + #ifdef WANT_DEBUG + if (sendAll) { + qDebug() << "SENDING -- rotations:" << rotationSentCount << "translations:" << translationSentCount + << "largest:" << maxTranslationDimension + << "radix:" << translationCompressionRadix + << "size:" << (int)(destinationBuffer - startPosition); + } + #endif + return avatarDataByteArray.left(destinationBuffer - startPosition); } @@ -328,7 +405,16 @@ void AvatarData::doneEncoding(bool cullSmallChanges) { if (_lastSentJointData[i].rotation != data.rotation) { if (!cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { - _lastSentJointData[i].rotation = data.rotation; + if (data.rotationSet) { + _lastSentJointData[i].rotation = data.rotation; + } + } + + if (!cullSmallChanges || + glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { + if (data.translationSet) { + _lastSentJointData[i].translation = data.translation; + } } } } @@ -374,7 +460,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { // + 1 byte for numJoints (0) // = 39 bytes int minPossibleSize = 39; - + int maxAvailableSize = buffer.size(); if (minPossibleSize > maxAvailableSize) { if (shouldLogError(now)) { @@ -556,7 +642,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f); } // 1 byte - // joint data + + //----------------------- + // joint rotations + //----------------------- + int numJoints = *sourceBuffer++; int bytesOfValidity = (int)ceil((float)numJoints / (float)BITS_IN_BYTE); minPossibleSize += bytesOfValidity; @@ -569,13 +659,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } return maxAvailableSize; } - int numValidJoints = 0; + int numValidJointRotations = 0; _jointData.resize(numJoints); - QVector valids; - valids.resize(numJoints); + QVector validRotations; + validRotations.resize(numJoints); - { // validity bits + { // rotation validity bits unsigned char validity = 0; int validityBit = 0; for (int i = 0; i < numJoints; i++) { @@ -584,20 +674,19 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } bool valid = (bool)(validity & (1 << validityBit)); if (valid) { - ++numValidJoints; + ++numValidJointRotations; } - valids[i] = valid; + validRotations[i] = valid; validityBit = (validityBit + 1) % BITS_IN_BYTE; } - } - // 1 + bytesOfValidity bytes + } // 1 + bytesOfValidity bytes // each joint rotation component is stored in two bytes (sizeof(uint16_t)) int COMPONENTS_PER_QUATERNION = 4; - minPossibleSize += numValidJoints * COMPONENTS_PER_QUATERNION * sizeof(uint16_t); + minPossibleSize += numValidJointRotations * COMPONENTS_PER_QUATERNION * sizeof(uint16_t); if (minPossibleSize > maxAvailableSize) { if (shouldLogError(now)) { - qCDebug(avatars) << "Malformed AvatarData packet after JointData;" + qCDebug(avatars) << "Malformed AvatarData packet after JointData rotation validity;" << " displayName = '" << _displayName << "'" << " minPossibleSize = " << minPossibleSize << " maxAvailableSize = " << maxAvailableSize; @@ -608,13 +697,75 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { { // joint data for (int i = 0; i < numJoints; i++) { JointData& data = _jointData[i]; - if (valids[i]) { + if (validRotations[i]) { _hasNewJointRotations = true; + data.rotationSet = true; sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); } } } // numJoints * 8 bytes + + //----------------------- + // joint translations + //----------------------- + + // get translation validity bits -- these indicate which translations were packed + int numValidJointTranslations = 0; + QVector validTranslations; + validTranslations.resize(numJoints); + + { // translation validity bits + unsigned char validity = 0; + int validityBit = 0; + for (int i = 0; i < numJoints; i++) { + if (validityBit == 0) { + validity = *sourceBuffer++; + } + bool valid = (bool)(validity & (1 << validityBit)); + if (valid) { + ++numValidJointTranslations; + } + validTranslations[i] = valid; + validityBit = (validityBit + 1) % BITS_IN_BYTE; + } + } // 1 + bytesOfValidity bytes + + // each joint translation component is stored in 6 bytes. 1 byte for translationCompressionRadix + minPossibleSize += numValidJointTranslations * 6 + 1; + if (minPossibleSize > maxAvailableSize) { + if (shouldLogError(now)) { + qCDebug(avatars) << "Malformed AvatarData packet after JointData translation validity;" + << " displayName = '" << _displayName << "'" + << " minPossibleSize = " << minPossibleSize + << " maxAvailableSize = " << maxAvailableSize; + } + return maxAvailableSize; + } + + int translationCompressionRadix = *sourceBuffer++; + + { // joint data + for (int i = 0; i < numJoints; i++) { + JointData& data = _jointData[i]; + if (validTranslations[i]) { + sourceBuffer += + unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, translationCompressionRadix); + _hasNewJointTranslations = true; + data.translationSet = true; + } + } + } // numJoints * 12 bytes + + #ifdef WANT_DEBUG + if (numValidJointRotations > 15) { + qDebug() << "RECEIVING -- rotations:" << numValidJointRotations + << "translations:" << numValidJointTranslations + << "radix:" << translationCompressionRadix + << "size:" << (int)(sourceBuffer - startPosition); + } + #endif + int numBytesRead = sourceBuffer - startPosition; _averageBytesReceived.updateAverage(numBytesRead); return numBytesRead; @@ -800,7 +951,7 @@ void AvatarData::changeReferential(Referential* ref) { _referential = ref; } -void AvatarData::setJointData(int index, const glm::quat& rotation) { +void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) { if (index == -1) { return; } @@ -813,6 +964,7 @@ void AvatarData::setJointData(int index, const glm::quat& rotation) { } JointData& data = _jointData[index]; data.rotation = rotation; + data.translation = translation; } void AvatarData::clearJointData(int index) { @@ -854,13 +1006,67 @@ glm::quat AvatarData::getJointRotation(int index) const { return index < _jointData.size() ? _jointData.at(index).rotation : glm::quat(); } -void AvatarData::setJointData(const QString& name, const glm::quat& rotation) { + +glm::vec3 AvatarData::getJointTranslation(int index) const { + if (index == -1) { + return glm::vec3(); + } + if (QThread::currentThread() != thread()) { + glm::vec3 result; + QMetaObject::invokeMethod(const_cast(this), "getJointTranslation", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(glm::vec3, result), Q_ARG(int, index)); + return result; + } + return index < _jointData.size() ? _jointData.at(index).translation : glm::vec3(); +} + +glm::vec3 AvatarData::getJointTranslation(const QString& name) const { + if (QThread::currentThread() != thread()) { + glm::vec3 result; + QMetaObject::invokeMethod(const_cast(this), "getJointTranslation", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(glm::vec3, result), Q_ARG(const QString&, name)); + return result; + } + return getJointTranslation(getJointIndex(name)); +} + +void AvatarData::setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "setJointData", Q_ARG(const QString&, name), Q_ARG(const glm::quat&, rotation)); return; } - setJointData(getJointIndex(name), rotation); + setJointData(getJointIndex(name), rotation, translation); +} + +void AvatarData::setJointRotation(int index, const glm::quat& rotation) { + if (index == -1) { + return; + } + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setJointRotation", Q_ARG(int, index), Q_ARG(const glm::quat&, rotation)); + return; + } + if (_jointData.size() <= index) { + _jointData.resize(index + 1); + } + JointData& data = _jointData[index]; + data.rotation = rotation; +} + +void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { + if (index == -1) { + return; + } + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setJointTranslation", Q_ARG(int, index), Q_ARG(const glm::vec3&, translation)); + return; + } + if (_jointData.size() <= index) { + _jointData.resize(index + 1); + } + JointData& data = _jointData[index]; + data.translation = translation; } void AvatarData::clearJointData(const QString& name) { @@ -918,7 +1124,25 @@ void AvatarData::setJointRotations(QVector jointRotations) { } for (int i = 0; i < jointRotations.size(); ++i) { if (i < _jointData.size()) { - setJointData(i, jointRotations[i]); + setJointRotation(i, jointRotations[i]); + } + } +} + +void AvatarData::setJointTranslations(QVector jointTranslations) { + if (QThread::currentThread() != thread()) { + QVector result; + QMetaObject::invokeMethod(const_cast(this), + "setJointTranslations", Qt::BlockingQueuedConnection, + Q_ARG(QVector, jointTranslations)); + } + + if (_jointData.size() < jointTranslations.size()) { + _jointData.resize(jointTranslations.size()); + } + for (int i = 0; i < jointTranslations.size(); ++i) { + if (i < _jointData.size()) { + setJointTranslation(i, jointTranslations[i]); } } } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a934b98037..e4022fd474 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -117,6 +117,7 @@ const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default"); const float AVATAR_SEND_FULL_UPDATE_RATIO = 0.02f; // this controls how large a change in joint-rotation must be before the interface sends it to the avatar mixer const float AVATAR_MIN_ROTATION_DOT = 0.9999999f; +const float AVATAR_MIN_TRANSLATION = 0.0001f; // Where one's own Avatar begins in the world (will be overwritten if avatar data file is found). @@ -240,20 +241,24 @@ public: Q_INVOKABLE char getHandState() const { return _handState; } const QVector& getJointData() const { return _jointData; } - void setJointData(const QVector& jointData) { _jointData = jointData; } - Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation); + Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation); + Q_INVOKABLE virtual void setJointRotation(int index, const glm::quat& rotation); + Q_INVOKABLE virtual void setJointTranslation(int index, const glm::vec3& translation); Q_INVOKABLE virtual void clearJointData(int index); Q_INVOKABLE bool isJointDataValid(int index) const; Q_INVOKABLE virtual glm::quat getJointRotation(int index) const; + Q_INVOKABLE virtual glm::vec3 getJointTranslation(int index) const; - Q_INVOKABLE void setJointData(const QString& name, const glm::quat& rotation); + Q_INVOKABLE void setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation); Q_INVOKABLE void clearJointData(const QString& name); Q_INVOKABLE bool isJointDataValid(const QString& name) const; Q_INVOKABLE glm::quat getJointRotation(const QString& name) const; + Q_INVOKABLE glm::vec3 getJointTranslation(const QString& name) const; Q_INVOKABLE virtual QVector getJointRotations() const; Q_INVOKABLE virtual void setJointRotations(QVector jointRotations); + Q_INVOKABLE virtual void setJointTranslations(QVector jointTranslations); Q_INVOKABLE virtual void clearJointsData(); @@ -387,6 +392,7 @@ protected: bool _forceFaceTrackerConnected; bool _hasNewJointRotations; // set in AvatarData, cleared in Avatar + bool _hasNewJointTranslations; // set in AvatarData, cleared in Avatar HeadData* _headData; HandData* _handData; @@ -435,6 +441,9 @@ Q_DECLARE_METATYPE(AvatarData*) class JointData { public: glm::quat rotation; + bool rotationSet = false; + glm::vec3 translation; + bool translationSet = false; }; class AttachmentData { diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 29544924b2..a425323a41 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -254,8 +254,17 @@ void Player::play() { nextFrame.getJointRotations()[i], _frameInterpolationFactor); } + + QVector jointTranslations(currentFrame.getJointTranslations().size()); + for (int i = 0; i < currentFrame.getJointTranslations().size(); ++i) { + jointTranslations[i] = + currentFrame.getJointTranslations()[i] * (1.0f - _frameInterpolationFactor) + + nextFrame.getJointTranslations()[i] * _frameInterpolationFactor; + } + _avatar->setJointRotations(jointRotations); - + _avatar->setJointTranslations(jointTranslations); + HeadData* head = const_cast(_avatar->getHeadData()); if (head) { // Make sure fake face tracker connection doesn't get turned off diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 76e1d68050..2c87485d01 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -239,6 +239,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) { if (i == 0 || frame._jointRotations[j] != previousFrame._jointRotations[j]) { writeQuat(stream, frame._jointRotations[j]); + // XXX handle translations mask.setBit(maskIndex); } maskIndex++; @@ -561,7 +562,10 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString frame._jointRotations[j] = previousFrame._jointRotations[j]; } } - + + // XXX handle translations + + if (!mask[maskIndex++] || !readVec3(stream, frame._translation)) { frame._translation = previousFrame._translation; } @@ -670,7 +674,9 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr for (int i = 0; i < jointRotationSize; ++i) { fileStream >> baseFrame._jointRotations[i].x >> baseFrame._jointRotations[i].y >> baseFrame._jointRotations[i].z >> baseFrame._jointRotations[i].w; } - + + // XXX handle translations + fileStream >> baseFrame._translation.x >> baseFrame._translation.y >> baseFrame._translation.z; fileStream >> baseFrame._rotation.x >> baseFrame._rotation.y >> baseFrame._rotation.z >> baseFrame._rotation.w; fileStream >> baseFrame._scale; @@ -736,7 +742,9 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr frame._jointRotations[i] = previousFrame._jointRotations[i]; } } - + + // XXX handle translations + if (mask[maskIndex++]) { stream >> frame._translation.x >> frame._translation.y >> frame._translation.z; frame._translation = context.orientationInv * frame._translation; diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index 49d12ec5b5..3533af6535 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -83,6 +83,7 @@ class RecordingFrame { public: QVector getBlendshapeCoefficients() const { return _blendshapeCoefficients; } QVector getJointRotations() const { return _jointRotations; } + QVector getJointTranslations() const { return _jointTranslations; } glm::vec3 getTranslation() const { return _translation; } glm::quat getRotation() const { return _rotation; } float getScale() const { return _scale; } @@ -94,6 +95,7 @@ public: protected: void setBlendshapeCoefficients(QVector blendshapeCoefficients); void setJointRotations(QVector jointRotations) { _jointRotations = jointRotations; } + void setJointTranslations(QVector jointTranslations) { _jointTranslations = jointTranslations; } void setTranslation(const glm::vec3& translation) { _translation = translation; } void setRotation(const glm::quat& rotation) { _rotation = rotation; } void setScale(float scale) { _scale = scale; } @@ -105,6 +107,7 @@ protected: private: QVector _blendshapeCoefficients; QVector _jointRotations; + QVector _jointTranslations; glm::vec3 _translation; glm::quat _rotation; float _scale; @@ -124,4 +127,4 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename); RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename); RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); -#endif // hifi_Recording_h \ No newline at end of file +#endif // hifi_Recording_h diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 74317b7eff..6d7399b07a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -276,10 +276,13 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (jointsMapped()) { bool newFrame; - auto frameData = getAnimationFrame(newFrame); + QVector frameDataRotations; + QVector frameDataTranslations; + getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); + assert(frameDataRotations.size() == frameDataTranslations.size()); if (newFrame) { - for (int i = 0; i < frameData.size(); i++) { - _model->setJointState(i, true, frameData[i]); + for (int i = 0; i < frameDataRotations.size(); i++) { + _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); } } } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 70747937d8..44b4aa99bf 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -218,18 +218,20 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { } } -const QVector& ModelEntityItem::getAnimationFrame(bool& newFrame) { +void ModelEntityItem::getAnimationFrame(bool& newFrame, + QVector& rotationsResult, QVector& translationsResult) { newFrame = false; if (!hasAnimation() || !_jointMappingCompleted) { - return _lastKnownFrameData; + rotationsResult = _lastKnownFrameDataRotations; + translationsResult = _lastKnownFrameDataTranslations; } - + AnimationPointer myAnimation = getAnimation(_animationURL); // FIXME: this could be optimized if (myAnimation && myAnimation->isLoaded()) { - + const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy - + int frameCount = frames.size(); if (frameCount > 0) { int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; @@ -240,20 +242,27 @@ const QVector& ModelEntityItem::getAnimationFrame(bool& newFrame) { if (animationFrameIndex != _lastKnownFrameIndex) { _lastKnownFrameIndex = animationFrameIndex; newFrame = true; - - const QVector& rotations = frames[animationFrameIndex].rotations; - _lastKnownFrameData.resize(_jointMapping.size()); + const QVector& rotations = frames[animationFrameIndex].rotations; + const QVector& translations = frames[animationFrameIndex].translations; + + _lastKnownFrameDataRotations.resize(_jointMapping.size()); + _lastKnownFrameDataTranslations.resize(_jointMapping.size()); for (int j = 0; j < _jointMapping.size(); j++) { - int rotationIndex = _jointMapping[j]; - if (rotationIndex != -1 && rotationIndex < rotations.size()) { - _lastKnownFrameData[j] = rotations[rotationIndex]; + int index = _jointMapping[j]; + if (index != -1 && index < rotations.size()) { + _lastKnownFrameDataRotations[j] = rotations[index]; + } + if (index != -1 && index < translations.size()) { + _lastKnownFrameDataTranslations[j] = translations[index]; } } } } } - return _lastKnownFrameData; + + rotationsResult = _lastKnownFrameDataRotations; + translationsResult = _lastKnownFrameDataTranslations; } bool ModelEntityItem::isAnimatingSomething() const { diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index bf6d7a9785..8bf6658bf3 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -106,7 +106,7 @@ public: float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } void mapJoints(const QStringList& modelJointNames); - const QVector& getAnimationFrame(bool& newFrame); + void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); bool jointsMapped() const { return _jointMappingCompleted; } bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } @@ -123,7 +123,8 @@ public: static void cleanupLoadedAnimations(); protected: - QVector _lastKnownFrameData; + QVector _lastKnownFrameDataRotations; + QVector _lastKnownFrameDataTranslations; int _lastKnownFrameIndex; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index da240e826a..1accbf4238 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -530,6 +530,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QHash typeFlags; QHash localRotations; + QHash localTranslations; QHash xComponents; QHash yComponents; QHash zComponents; @@ -1104,16 +1105,16 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("specular") || type.contains("reflection")) { specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - + } else if (type == "lcl rotation") { localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - + } else if (type == "lcl translation") { + localTranslations.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + } else if (type == "d|x") { xComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type == "d|y") { yComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type == "d|z") { zComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); @@ -1224,6 +1225,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS for (int i = 0; i < frameCount; i++) { FBXAnimationFrame frame; frame.rotations.resize(modelIDs.size()); + frame.translations.resize(modelIDs.size()); geometry.animationFrames.append(frame); } @@ -1247,7 +1249,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS joint.freeLineage.append(index); } joint.freeLineage.remove(lastFreeIndex + 1, joint.freeLineage.size() - lastFreeIndex - 1); - joint.translation = model.translation; + joint.translation = model.translation; // these are usually in centimeters joint.preTransform = model.preTransform; joint.preRotation = model.preRotation; joint.rotation = model.rotation; @@ -1272,7 +1274,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = model.name; - + foreach (const QString& childID, _connectionChildMap.values(modelID)) { QString type = typeFlags.value(childID); if (!type.isEmpty()) { @@ -1285,17 +1287,28 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS geometry.joints.append(joint); geometry.jointIndices.insert(model.name, geometry.joints.size()); - + QString rotationID = localRotations.value(modelID); - AnimationCurve xCurve = animationCurves.value(xComponents.value(rotationID)); - AnimationCurve yCurve = animationCurves.value(yComponents.value(rotationID)); - AnimationCurve zCurve = animationCurves.value(zComponents.value(rotationID)); + AnimationCurve xRotCurve = animationCurves.value(xComponents.value(rotationID)); + AnimationCurve yRotCurve = animationCurves.value(yComponents.value(rotationID)); + AnimationCurve zRotCurve = animationCurves.value(zComponents.value(rotationID)); + + QString translationID = localTranslations.value(modelID); + AnimationCurve xPosCurve = animationCurves.value(xComponents.value(translationID)); + AnimationCurve yPosCurve = animationCurves.value(yComponents.value(translationID)); + AnimationCurve zPosCurve = animationCurves.value(zComponents.value(translationID)); + glm::vec3 defaultValues = glm::degrees(safeEulerAngles(joint.rotation)); + for (int i = 0; i < frameCount; i++) { geometry.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3( - xCurve.values.isEmpty() ? defaultValues.x : xCurve.values.at(i % xCurve.values.size()), - yCurve.values.isEmpty() ? defaultValues.y : yCurve.values.at(i % yCurve.values.size()), - zCurve.values.isEmpty() ? defaultValues.z : zCurve.values.at(i % zCurve.values.size())))); + xRotCurve.values.isEmpty() ? defaultValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), + yRotCurve.values.isEmpty() ? defaultValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), + zRotCurve.values.isEmpty() ? defaultValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); + geometry.animationFrames[i].translations[jointIndex] = glm::vec3( + xPosCurve.values.isEmpty() ? defaultValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), + yPosCurve.values.isEmpty() ? defaultValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), + zPosCurve.values.isEmpty() ? defaultValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); } } diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 5cfff9826f..20f8fffe44 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -208,8 +208,8 @@ public: /// A single animation frame extracted from an FBX document. class FBXAnimationFrame { public: - QVector rotations; + QVector translations; }; /// A light in an FBX document. diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a8cf743686..ca75a86158 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -39,6 +39,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: return VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER; + case PacketType::AvatarData: + case PacketType::BulkAvatarData: + return 15; default: return 14; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7aee46b108..34896d5714 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1001,8 +1001,16 @@ void Model::clearJointState(int index) { _rig->clearJointState(index); } -void Model::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { - _rig->setJointState(index, valid, rotation, priority); +void Model::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + _rig->setJointState(index, valid, rotation, translation, priority); +} + +void Model::setJointRotation(int index, bool valid, const glm::quat& rotation, float priority) { + _rig->setJointRotation(index, valid, rotation, priority); +} + +void Model::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) { + _rig->setJointTranslation(index, valid, translation, priority); } int Model::getParentJointIndex(int jointIndex) const { @@ -1074,6 +1082,10 @@ bool Model::getJointRotation(int jointIndex, glm::quat& rotation) const { return _rig->getJointRotation(jointIndex, rotation); } +bool Model::getJointTranslation(int jointIndex, glm::vec3& translation) const { + return _rig->getJointTranslation(jointIndex, translation); +} + bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { return _rig->getJointCombinedRotation(jointIndex, rotation, _rotation); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index de760dc793..460bc4f044 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -126,7 +126,9 @@ public: QStringList getJointNames() const; /// Sets the joint state at the specified index. - void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat(), float priority = 1.0f); + void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); + void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority); + void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false); @@ -160,6 +162,7 @@ public: /// \param rotation[out] rotation of joint in model-frame /// \return true if joint exists bool getJointRotation(int jointIndex, glm::quat& rotation) const; + bool getJointTranslation(int jointIndex, glm::vec3& translation) const; /// Returns the index of the parent of the indexed joint, or -1 if not found. int getParentJointIndex(int jointIndex) const; diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 7d56157e53..31a6096d13 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -33,6 +33,8 @@ const vec3& Vectors::RIGHT = Vectors::UNIT_X; const vec3& Vectors::UP = Vectors::UNIT_Y; const vec3& Vectors::FRONT = Vectors::UNIT_NEG_Z; +const quat Quaternions::ZERO{ 1.0f, 0.0f, 0.0f, 0.0f }; + // Safe version of glm::mix; based on the code in Nick Bobick's article, // http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde, // https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 6683088306..e2833b46e3 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -53,6 +53,12 @@ const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f); glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha); + +class Quaternions { + public: + static const quat ZERO; +}; + class Vectors { public: static const vec3 UNIT_X; From 46fabf964dfdc61288279521ed1a58a959697414 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:54:57 -0700 Subject: [PATCH 172/418] cleanup --- examples/particle_explorer/main.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 057932f309..f98c09a321 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -111,7 +111,6 @@ window.onload = function() { controller.shouldGroup = false; } - //keep track of our controller controllers.push(controller); @@ -135,17 +134,15 @@ function writeDataToInterface(property, value, shouldGroup) { var group = null; var groupProperty = null; var groupProperties = null; + if (shouldGroup) { var separated = property.slice(0, property.indexOf('_group')).split("_") group = separated[0]; groupProperty = separated[1]; - var groupString = group.toString(); - var groupPropertyString = groupProperty.toString(); var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value // console.log(groupProperties) - } var data = { From f84762f2d7adabbbef8608852f402e5aaf16cde0 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:02:59 -0700 Subject: [PATCH 173/418] remove old gui file --- examples/particle_explorer/old.html | 1607 --------------------------- 1 file changed, 1607 deletions(-) delete mode 100644 examples/particle_explorer/old.html diff --git a/examples/particle_explorer/old.html b/examples/particle_explorer/old.html deleted file mode 100644 index f2d91bda70..0000000000 --- a/examples/particle_explorer/old.html +++ /dev/null @@ -1,1607 +0,0 @@ - - - Properties - - - - - - - - -
    -
    -
    - -
    -
    -
    - - - -
    - -
    -
    -
    - Name -
    - -
    -
    - -
    - Locked - - - -
    - -
    - Visible - - - -
    - -
    -
    User Data
    -
    - -
    -
    - - -
    - -
    - -
    -
    Href
    -
    - -
    -
    -
    -
    Description
    -
    - -
    -
    - - -
    - -
    - -
    -
    Position
    -
    -
    X
    -
    Y
    -
    Z
    -
    - - -
    -
    -
    - -
    -
    Registration
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Dimensions
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    -
    - % -
    - - - -
    -
    - -
    -
    Voxel Volume Size
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    Surface Extractor
    -
    - -
    - -
    X-axis Texture URL
    -
    - -
    - -
    Y-axis Texture URL
    -
    - -
    - -
    Z-axis Texture URL
    -
    - -
    -
    - -
    -
    Rotation
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    - - -
    - -
    - -
    -
    Linear Velocity
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    -
    -
    Linear Damping
    -
    - -
    -
    -
    -
    Angular Velocity
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    -
    -
    Angular Damping
    -
    - -
    -
    -
    -
    Restitution
    -
    - -
    -
    -
    -
    Friction
    -
    - -
    -
    - -
    -
    Gravity
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Acceleration
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Density
    -
    - -
    -
    - -
    -
    Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    - - -
    - -
    - -
    - Ignore For Collisions - - - -
    - -
    - Collisions Will Move - - - -
    - -
    -
    Collision Sound URL
    -
    - -
    -
    - -
    -
    Lifetime
    -
    - -
    -
    - -
    -
    Script URL - - -
    -
    - -
    -
    - - -
    - -
    - -
    -
    Model URL
    -
    - -
    -
    - -
    -
    Shape Type
    -
    - -
    -
    -
    -
    Compound Shape URL
    -
    - -
    -
    -
    -
    Animation URL
    -
    - -
    -
    -
    - Animation Playing - - - -
    -
    -
    Animation FPS
    -
    - -
    -
    -
    -
    Animation Frame
    -
    - -
    -
    -
    -
    Animation Settings
    -
    - -
    -
    -
    -
    Textures
    -
    - -
    -
    -
    -
    Original Textures
    -
    - -
    -
    - - -
    - -
    - -
    -
    Source URL
    -
    - -
    -
    - - -
    - -
    - -
    -
    Max Particles
    -
    - -
    -
    -
    -
    Particle Life Span
    -
    - -
    -
    -
    -
    Particle Emission Rate
    -
    - -
    -
    -
    -
    Particle Emission Direction
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    -
    -
    Particle Emission Strength
    -
    - -
    -
    -
    -
    Particle Local Gravity
    -
    - -
    -
    -
    -
    Particle Radius
    -
    - -
    -
    - - -
    - -
    - -
    -
    Text Content
    -
    - -
    -
    -
    -
    Line Height
    -
    - -
    -
    -
    -
    Text Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Background Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    - - -
    - -
    - -
    - Spot Light - - - -
    -
    -
    Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Intensity
    -
    - -
    -
    -
    -
    Spot Light Exponent
    -
    - -
    -
    -
    -
    Spot Light Cutoff (degrees)
    -
    - -
    -
    - - -
    - -
    - -
    - Stage Sun Model Enabled - - - -
    - -
    -
    Key Light Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Key Light Intensity
    -
    - -
    -
    -
    -
    Key Light Ambient Intensity
    -
    - -
    -
    -
    -
    Key Light Direction
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    - -
    -
    Stage Latitude
    -
    - -
    -
    -
    -
    Stage Longitude
    -
    - -
    -
    -
    -
    Stage Altitude
    -
    - -
    -
    - -
    - Automatically calculate stage hour and day from location and clock. - - - -
    - -
    -
    Stage Day
    -
    - -
    -
    -
    -
    Stage Hour
    -
    - -
    -
    - -
    -
    Background Mode
    -
    - -
    -
    - - -
    - -
    - -
    -
    Skybox Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Skybox URL
    -
    - -
    -
    - - -
    - -
    - -
    -
    Atmosphere Center
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    -
    -
    -
    -
    Atmosphere Inner Radius
    -
    - -
    -
    -
    -
    Atmosphere Outer Radius
    -
    - -
    -
    -
    -
    Atmosphere Mie Scattering
    -
    - -
    -
    -
    -
    Atmosphere Rayleigh Scattering
    -
    - -
    -
    -
    -
    Atmosphere Scattering Wavelenghts
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    - - \ No newline at end of file From f3c13f5d691208421663e7ecc1f74e3ed6a8feab Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:18:20 -0700 Subject: [PATCH 174/418] do grouping differently so names look better --- examples/particle_explorer/main.js | 76 +++++++++++++++++++----------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index f98c09a321..ba6938ee23 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -25,6 +25,17 @@ function radiansToDegrees(radians) { // property_subproperty_group = value // i.e. color_red_group = 0; +var groups = [ +'accelerationSpread', +'color', +'colorSpread', +'colorStart', +'colorFinish', +'emitAcceleration', +'emitDimensions', +'emitOrientation' +] + var ParticleExplorer = function() { this.animationIsPlaying = true; this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; @@ -32,36 +43,36 @@ var ParticleExplorer = function() { this.visible = false; this.locked = false; this.lifetime = 3600 // 1 hour; just in case - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; + this.accelerationSpread_x = 0.1; + this.accelerationSpread_y = 0.1; + this.accelerationSpread_z = 0.1; this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; + this.color_red= 0; + this.color_green = 0; + this.color_blue = 0; + this.colorSpread_red= 0; + this.colorSpread_green = 0; + this.colorSpread_blue = 0; + this.colorStart_red = 0; + this.colorStart_green = 0; + this.colorStart_blue= 0; + this.colorFinish_red = 0; + this.colorFinish_green = 0; + this.colorFinish_blue = 0; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; + this.emitAcceleration_x= 0.01; + this.emitAcceleration_y = 0.01; + this.emitAcceleration_z= 0.01; + this.emitDimensions_x= 0.01; + this.emitDimensions_y = 0.01; + this.emitDimensions_z = 0.01; + this.emitOrientation_x = 0.01; + this.emitOrientation_y = 0.01; + this.emitOrientation_z = 0.01; + this.emitOrientation_w = 0.01; this.emitRate = 0.1; this.emitSpeed = 0.1; this.polarStart = 0.01; @@ -105,7 +116,15 @@ window.onload = function() { _.each(particleKeys, function(key) { //add this key as a controller to the gui var controller = gui.add(particleExplorer, key); - if (key.indexOf('_group') > -1) { + + var putInGroup = false; + _.each(groups,function(group){ + if(key.indexOf(group)>-1){ + putInGroup=true; + } + }) + + if (putInGroup===true) { controller.shouldGroup = true; } else { controller.shouldGroup = false; @@ -131,12 +150,14 @@ window.onload = function() { }; function writeDataToInterface(property, value, shouldGroup) { + // console.log('property, value, shouldGroup',property, value, shouldGroup) var group = null; var groupProperty = null; var groupProperties = null; if (shouldGroup) { - var separated = property.slice(0, property.indexOf('_group')).split("_") + var separated = property.split("_"); + console.log(separated) group = separated[0]; groupProperty = separated[1]; var groupProperties = {} @@ -156,6 +177,7 @@ function writeDataToInterface(property, value, shouldGroup) { var stringifiedData = JSON.stringify(data) + // console.log('stringifiedData',stringifiedData) if (typeof EventBridge !== 'undefined') { EventBridge.emitWebEvent( stringifiedData From f953456007cdf489049388f419859a667322243f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:21:55 -0700 Subject: [PATCH 175/418] comments --- examples/particle_explorer/main.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index ba6938ee23..0c22f8541a 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -21,10 +21,7 @@ function radiansToDegrees(radians) { return radians * (180 / PI) } -// need to add '_group' to the end of properties that will need to be made part of a group on the backend -// property_subproperty_group = value -// i.e. color_red_group = 0; - +//specify properties that are groups because we have to read them a little differently than single properties at the moment. var groups = [ 'accelerationSpread', 'color', From 51de351c50ac99427e7488832ca244f26b02bdee Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:28:15 -0700 Subject: [PATCH 176/418] convert tabs to spaces --- .../particle_explorer/particleExplorer.js | 232 +++++++++--------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index a39b3e0307..ad4fd36df7 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -5,7 +5,7 @@ // Created by James B. Pollack @imgntnon 9/26/2015 // Copyright 2014 High Fidelity, Inc. // -// Interface side of the App. +// Interface side of the App. // Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. // // Distributed under the Apache License, Version 2.0. @@ -14,148 +14,148 @@ // todo: folders, color pickers, animation settings, scale gui width with window resizing // var boxPoint, - spawnPoint, - animation = { - fps: 30, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 30, - loop: true - }; + spawnPoint, + animation = { + fps: 30, + frameIndex: 0, + running: true, + firstFrame: 0, + lastFrame: 30, + loop: true + }; var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { - x: 0.0, - y: -0.5, - z: 0.0 + x: 0.0, + y: -0.5, + z: 0.0 }); spawnPoint = Vec3.sum(boxPoint, { - x: 0.0, - y: 1.0, - z: 0.0 + x: 0.0, + y: 1.0, + z: 0.0 }); var PI = 3.141593, - DEG_TO_RAD = PI / 180.0; + DEG_TO_RAD = PI / 180.0; BlankBox = function() { - this.animationIsPlaying = true; - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; - this.alpha = 0.5; - this.alphaStart = 1.0; - this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; - this.azimuthStart = -PI / 2.0; - this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; - this.emitRate = 0.1; - this.emitSpeed = 0.1; - this.polarStart = 0.01; - this.polarFinish = 2.0 * DEG_TO_RAD; - this.speedSpread = 0.1; - this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; - // - this.type = "ParticleEffect"; - this.name = "ParticlesTest Emitter"; - this.position = spawnPoint; - this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; - this.lifespan = 5.0; - this.visible = false; - this.locked = false; - this.animationSettings = animation; - this.lifetime = 3600 // 1 hour; just in case + this.animationIsPlaying = true; + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + // + this.type = "ParticleEffect"; + this.name = "ParticlesTest Emitter"; + this.position = spawnPoint; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.animationSettings = animation; + this.lifetime = 3600 // 1 hour; just in case } var blankBox = new BlankBox(); var box = Entities.addEntity({ - type: "Box", - name: "ParticlesTest Box", - position: boxPoint, - rotation: { - x: -0.7071067690849304, - y: 0, - z: 0, - w: 0.7071067690849304 - }, - dimensions: { - x: 0.3, - y: 0.3, - z: 0.3 - }, - color: { - red: 128, - green: 128, - blue: 128 - }, - lifetime: 3600, // 1 hour; just in case - visible: true + type: "Box", + name: "ParticlesTest Box", + position: boxPoint, + rotation: { + x: -0.7071067690849304, + y: 0, + z: 0, + w: 0.7071067690849304 + }, + dimensions: { + x: 0.3, + y: 0.3, + z: 0.3 + }, + color: { + red: 128, + green: 128, + blue: 128 + }, + lifetime: 3600, // 1 hour; just in case + visible: true }); var testParticles = Entities.addEntity(blankBox); SettingsWindow = function() { - var _this = this; - this.webWindow = null; - this.init = function() { - _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); - _this.webWindow.setVisible(true); - _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); - print('INIT testParticles' + testParticles) - }; - this.onWebEventReceived = function(data) { - // print('DATA ' + data) - var _data = JSON.parse(data) - if (_data.type !== 'particleExplorer_update') { - return; - } - if (_data.shouldGroup === true) { - // print('USE GROUP PROPERTIES') - editEntity(_data.groupProperties) - return; - } else { - // print('USE A SINGLE PROPERTY') - editEntity(_data.singleProperty) + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + print('INIT testParticles' + testParticles) + }; + this.onWebEventReceived = function(data) { + // print('DATA ' + data) + var _data = JSON.parse(data) + if (_data.type !== 'particleExplorer_update') { + return; + } + if (_data.shouldGroup === true) { + // print('USE GROUP PROPERTIES') + editEntity(_data.groupProperties) + return; + } else { + // print('USE A SINGLE PROPERTY') + editEntity(_data.singleProperty) - } + } - }; + }; } function editEntity(properties) { - Entities.editEntity(testParticles, properties); - var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + Entities.editEntity(testParticles, properties); + var currentProperties = Entities.getEntityProperties(testParticles) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } @@ -163,7 +163,7 @@ var settingsWindow = new SettingsWindow(); settingsWindow.init(); function cleanup() { - Entities.deleteEntity(testParticles); - Entities.deleteEntity(box); + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 22515a9375e1127e99f1adcd7ec8f1234e2cac19 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:40:46 -0700 Subject: [PATCH 177/418] fix naming, match initial properties --- examples/particle_explorer/main.js | 6 +- .../particle_explorer/particleExplorer.js | 87 +++++++++++-------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 0c22f8541a..eca05ff303 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -76,9 +76,9 @@ var ParticleExplorer = function() { this.polarFinish = 2.0 * DEG_TO_RAD; this.speedSpread = 0.1; this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; + this.radiusStart = 0.1; + this.radiusFinish = 0.1; + this.velocitySpread = 0.1; } diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index ad4fd36df7..5b34ea5b13 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -24,7 +24,6 @@ var boxPoint, loop: true }; - var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { x: 0.0, @@ -40,48 +39,65 @@ spawnPoint = Vec3.sum(boxPoint, { var PI = 3.141593, DEG_TO_RAD = PI / 180.0; -BlankBox = function() { +StartingParticles = function() { this.animationIsPlaying = true; - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; + this.accelerationSpread = { + x: 0.1, + y: 0.1, + z: 0.1 + }; this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; + this.color = { + red: 0, + green: 0, + blue: 0 + }; + this.colorSpread = { + red: 0, + green: 0, + blue: 0 + }; + + this.colorStart = { + red: 0, + green: 0, + blue: 0 + }; + + this.colorFinish = { + red: 0, + green: 0, + blue: 0 + }; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; + this.emitAccceleration = { + x: 0.1, + y: 0.1, + z: 0.1 + }; + this.emitDimensions = { + x: 0.01, + y: 0.01, + z: 0.01 + }; + this.emitOrientation = { + x: 0.01, + y: 0.01, + z: 0.01, + w: 0.01 + }; this.emitRate = 0.1; this.emitSpeed = 0.1; this.polarStart = 0.01; this.polarFinish = 2.0 * DEG_TO_RAD; this.speedSpread = 0.1; this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; - // + this.radiusStart = 0.1; + this.radiusFinish = 0.1; + this.velocitySpread = 0.1; this.type = "ParticleEffect"; this.name = "ParticlesTest Emitter"; this.position = spawnPoint; @@ -93,7 +109,7 @@ BlankBox = function() { this.lifetime = 3600 // 1 hour; just in case } -var blankBox = new BlankBox(); +var startingParticles = new StartingParticles(); var box = Entities.addEntity({ type: "Box", @@ -115,11 +131,10 @@ var box = Entities.addEntity({ green: 128, blue: 128 }, - lifetime: 3600, // 1 hour; just in case - visible: true + }); -var testParticles = Entities.addEntity(blankBox); +var testParticles = Entities.addEntity(startingParticles); SettingsWindow = function() { var _this = this; @@ -155,7 +170,7 @@ SettingsWindow = function() { function editEntity(properties) { Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } From 5013e98b6cd4ac27eaeb4b92b880fb3257d64034 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:47:22 -0700 Subject: [PATCH 178/418] cleanup, comments --- examples/particle_explorer/index.html | 2 +- examples/particle_explorer/main.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 1bcbba05da..a389bf125c 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -5,7 +5,7 @@ // Created by James B. Pollack @imgntnon 9/26/2015 // Copyright 2014 High Fidelity, Inc. // -// Web app side of the App - contains GUI. +// Loads dat.gui, underscore, and the app // Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. // // Distributed under the Apache License, Version 2.0. diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index eca05ff303..ae235b1846 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -154,7 +154,6 @@ function writeDataToInterface(property, value, shouldGroup) { if (shouldGroup) { var separated = property.split("_"); - console.log(separated) group = separated[0]; groupProperty = separated[1]; var groupProperties = {} From 7a59a7dc43a04304fd9a41907b7e4f129e460c1a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 14:10:30 -0700 Subject: [PATCH 179/418] add two-way code but dont enable --- examples/particle_explorer/main.js | 61 ++++++++++++------- .../particle_explorer/particleExplorer.js | 6 +- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index ae235b1846..93cdb02cbf 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -23,14 +23,14 @@ function radiansToDegrees(radians) { //specify properties that are groups because we have to read them a little differently than single properties at the moment. var groups = [ -'accelerationSpread', -'color', -'colorSpread', -'colorStart', -'colorFinish', -'emitAcceleration', -'emitDimensions', -'emitOrientation' + 'accelerationSpread', + 'color', + 'colorSpread', + 'colorStart', + 'colorFinish', + 'emitAcceleration', + 'emitDimensions', + 'emitOrientation' ] var ParticleExplorer = function() { @@ -46,24 +46,24 @@ var ParticleExplorer = function() { this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red= 0; + this.color_red = 0; this.color_green = 0; this.color_blue = 0; - this.colorSpread_red= 0; + this.colorSpread_red = 0; this.colorSpread_green = 0; this.colorSpread_blue = 0; this.colorStart_red = 0; this.colorStart_green = 0; - this.colorStart_blue= 0; + this.colorStart_blue = 0; this.colorFinish_red = 0; this.colorFinish_green = 0; this.colorFinish_blue = 0; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAcceleration_x= 0.01; + this.emitAcceleration_x = 0.01; this.emitAcceleration_y = 0.01; - this.emitAcceleration_z= 0.01; - this.emitDimensions_x= 0.01; + this.emitAcceleration_z = 0.01; + this.emitDimensions_x = 0.01; this.emitDimensions_y = 0.01; this.emitDimensions_z = 0.01; this.emitOrientation_x = 0.01; @@ -84,10 +84,11 @@ var ParticleExplorer = function() { //we need a way to keep track of our gui controllers var controllers = []; +var particleExplorer; window.onload = function() { //instantiate our object - var particleExplorer = new ParticleExplorer(); + particleExplorer = new ParticleExplorer(); //whether or not to autoplace var gui = new dat.GUI({ @@ -113,15 +114,17 @@ window.onload = function() { _.each(particleKeys, function(key) { //add this key as a controller to the gui var controller = gui.add(particleExplorer, key); + // the call below is potentially expensive but will enable two way binding. needs testing to see how many it supports at once. + //var controller = gui.add(particleExplorer, key).listen(); - var putInGroup = false; - _.each(groups,function(group){ - if(key.indexOf(group)>-1){ - putInGroup=true; + var putInGroup = false; + _.each(groups, function(group) { + if (key.indexOf(group) > -1) { + putInGroup = true; } }) - if (putInGroup===true) { + if (putInGroup === true) { controller.shouldGroup = true; } else { controller.shouldGroup = false; @@ -138,7 +141,7 @@ window.onload = function() { controller.onFinishChange(function(value) { // console.log('should group?', controller.shouldGroup) - // Fires when a controller loses focus. + // Fires when a controller loses focus. writeDataToInterface(this.property, value, this.shouldGroup) }); @@ -151,7 +154,7 @@ function writeDataToInterface(property, value, shouldGroup) { var group = null; var groupProperty = null; var groupProperties = null; - + if (shouldGroup) { var separated = property.split("_"); group = separated[0]; @@ -159,7 +162,7 @@ function writeDataToInterface(property, value, shouldGroup) { var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value - // console.log(groupProperties) + // console.log(groupProperties) } var data = { @@ -180,4 +183,16 @@ function writeDataToInterface(property, value, shouldGroup) { ); } +} + +function listenForSettingsUpdates() { + if (typeof EventBridge !== 'undefined') { + EventBridge.scriptEventReceived.connect(function(data) { + data = JSON.parse(data); + if (data.type === 'particleSettingsUpdate') { + var particleSettings = data.particleSettings + //parse the settings and change particle explorer, add .listen() to controllers + } + }); + } } \ No newline at end of file diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index 5b34ea5b13..bc5810d652 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -145,6 +145,9 @@ SettingsWindow = function() { _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); print('INIT testParticles' + testParticles) }; + this.sendData = function(data) { + _this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data)); + }; this.onWebEventReceived = function(data) { // print('DATA ' + data) var _data = JSON.parse(data) @@ -170,7 +173,8 @@ SettingsWindow = function() { function editEntity(properties) { Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) + SettingsWindow.sendData({type:'particleSettingsUpdate',particleSettings:currentProperties}) } From 06a646263637d8e66c7414cb7c8c29fc800224cf Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 14:14:21 -0700 Subject: [PATCH 180/418] add function for manually updating display --- examples/particle_explorer/main.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 93cdb02cbf..6b0531392d 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -195,4 +195,12 @@ function listenForSettingsUpdates() { } }); } +} + + +function manuallyUpdateDisplay(gui) { + // Iterate over all controllers + for (var i in gui.__controllers) { + gui.__controllers[i].updateDisplay(); + } } \ No newline at end of file From 4f7e7e1d5fb0ca2718e72e6f7875c85f4ebbf7e5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 23:24:00 -0700 Subject: [PATCH 181/418] start generic two-way implementation, fix some typos --- examples/particle_explorer/generic.js | 130 ++++++++++++++++++ .../particle_explorer/genericProperties.js | 99 +++++++++++++ examples/particle_explorer/index.html | 4 +- .../particle_explorer/particleExplorer.js | 2 +- 4 files changed, 232 insertions(+), 3 deletions(-) create mode 100644 examples/particle_explorer/generic.js create mode 100644 examples/particle_explorer/genericProperties.js diff --git a/examples/particle_explorer/generic.js b/examples/particle_explorer/generic.js new file mode 100644 index 0000000000..22510cc357 --- /dev/null +++ b/examples/particle_explorer/generic.js @@ -0,0 +1,130 @@ +// +// main.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Web app side of the App - contains GUI. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +var Settings = function() { + return; +} + +//we need a way to keep track of our gui controllers +var controllers = []; +var settings = new Settings(); + +function loadGUI() { + console.log('loadGUI loadGUI loadGUI loadGUI') + //instantiate our object + + //whether or not to autoplace + var gui = new dat.GUI({ + autoPlace: false + }); + + //if not autoplacing, put gui in a custom container + if (gui.autoPlace === false) { + + var customContainer = document.getElementById('my-gui-container'); + customContainer.appendChild(gui.domElement); + gui.width = 400; + + } + + //add save settings ability (try not to use localstorage) + gui.remember(settings); + + //get object keys + var keys = _.keys(settings); + + //for each key... + _.each(keys, function(key) { + console.log('KEY KEY KEY' + key); + //add this key as a controller to the gui + var controller = gui.add(settings, key).listen(); + // the call below is potentially expensive but will enable two way binding. needs testing to see how many it supports at once. + //var controller = gui.add(particleExplorer, key).listen(); + //keep track of our controller + controllers.push(controller); + + //hook into change events for this gui controller + controller.onChange(function(value) { + // Fires on every change, drag, keypress, etc. + }); + + controller.onFinishChange(function(value) { + // Fires when a controller loses focus. + writeDataToInterface(this.property, value) + }); + + }); + +}; + +function writeDataToInterface(property, value, shouldGroup) { + var data = { + type: "settings_update", + updatedSettings: settings, + } + + var stringifiedData = JSON.stringify(data) + + // console.log('stringifiedData',stringifiedData) + if (typeof EventBridge !== 'undefined') { + EventBridge.emitWebEvent( + stringifiedData + ); + } + +} + +function listenForSettingsUpdates() { + console.log('listening for messages') + if (typeof EventBridge !== 'undefined') { + console.log('WE HAVE AN EVENT BRIDGE') + EventBridge.scriptEventReceived.connect(function(data) { + console.log('GOT MESSAGE FROM EVENT BRIDGE') + data = JSON.parse(data); + if (data.messageType === 'initialSettings') { + console.log('INITIAL SETTINGS:::' + JSON.stringify(data.initialSettings)) + var initialSettings = data.initialSettings; + _.each(initialSettings, function(value, key) { + console.log('key ' + key); + console.log('value ' + JSON.stringify(value)); + + settings[key] = {}; + settings[key] = value; + }) + loadGUI(); + } + if (data.messageType === 'settingsUpdate') { + var initialSettings = data.updatedSettings; + _.each(initialSettings, function(value, key) { + console.log('setting,value', setting, value) + settings[key] = value; + }) + + + } + }); + } +} + + +function manuallyUpdateDisplay(gui) { + // Iterate over all controllers + for (var i in gui.__controllers) { + gui.__controllers[i].updateDisplay(); + } +} + +listenForSettingsUpdates(); \ No newline at end of file diff --git a/examples/particle_explorer/genericProperties.js b/examples/particle_explorer/genericProperties.js new file mode 100644 index 0000000000..2444d78d2d --- /dev/null +++ b/examples/particle_explorer/genericProperties.js @@ -0,0 +1,99 @@ +// +// particleExplorer.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Interface side of the App. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +SettingsWindow = function() { + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('genericProperties', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + var boxPoint; + + var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); + + _this.box = Entities.addEntity({ + type: 'box', + visible: true, + collisionsWillMove: true, + color: { + red: 0, + green: 255, + blue: 0 + + }, + dimensions: { + x: 1, + y: 1, + z: 1, + }, + position: boxPoint + }); + + }; + this.sendData = function(data) { + print('sending data' + JSON.stringify(data)); + _this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data)); + }; + this.onWebEventReceived = function(data) { + // print('DATA ' + data) + var _data = JSON.parse(data) + if (_data.type !== 'settings_update') { + return; + } + print('GOT A SETTINGS UPDATE EVENT') + editEntity(_data.updatedSettings) + + } + + +} + +function sendInitialSettings() { + + + var settings = { + messageType: 'initialSettings', + initialSettings: Entities.getEntityProperties(SettingsWindow.box) + } + settingsWindow.sendData(settings) + + + +} + +function editEntity(properties) { + Entities.editEntity(SettingsWindow.box, properties); + var currentProperties = Entities.getEntityProperties(SettingsWindow.box); + settingsWindow.sendData({ + messageType: 'settingsUpdate', + updatedSettings: currentProperties + }) +} + + +var settingsWindow = new SettingsWindow(); +settingsWindow.init(); +Script.setTimeout(function() { + sendInitialSettings(); +}, 1000) + + +function cleanup() { + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); +} +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index a389bf125c..033954ba73 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // // todo: folders, color pickers, animation settings, scale gui width with window resizing - --> + --> @@ -21,7 +21,7 @@ +
    +
    +    
    +
    +
    diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index b08823acc3..831d5a167a 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -13,6 +13,9 @@ /*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { + this.saveParticleSettings = function() { + showPreselectedPrompt(); + } return; }; @@ -136,9 +139,13 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); + gui.add(settings, 'saveParticleSettings'); addIndividualKeys(); addFolders(); + setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + // showParticleSettings(); + // showPreselectedPrompt(); } @@ -146,8 +153,8 @@ function addIndividualKeys() { _.each(individualKeys, function(key) { var controller = gui.add(settings, key) - //need to fix not being able to input values if constantly listening - //.listen(); + //need to fix not being able to input values if constantly listening + //.listen(); // keep track of our controller controllers.push(controller); @@ -382,4 +389,30 @@ function manuallyUpdateDisplay() { function removeContainerDomElement() { var elem = document.getElementById("my-gui-container"); elem.parentNode.removeChild(elem); +} + +function showParticleSettings() { + var codeBlock = document.getElementById("export-code"); + codeBlock.innerHTML = prepareSettingsForExport(); +} + + +function prepareSettingsForExport() { + var keys = _.keys(settings); + var exportSettings = {}; + //for each key... + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return + } + + exportSettings[key] = settings[key]; + }) + return JSON.stringify(exportSettings); +} + + +function showPreselectedPrompt() { + window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); } \ No newline at end of file From 8fc696c5f8eef9e288fde0c1a0212369863cf71b Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 12:41:08 -0700 Subject: [PATCH 329/418] add ability to explort particle settings in nice format for interface --- examples/particle_explorer/index.html | 5 ----- examples/particle_explorer/main.js | 21 +++++++++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index fdfd6f35c7..1772423d02 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -27,11 +27,6 @@ -
    -
    -    
    -
    -
    diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 831d5a167a..4db3f4b9e9 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -13,7 +13,7 @@ /*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { - this.saveParticleSettings = function() { + this.exportSettings = function() { showPreselectedPrompt(); } return; @@ -95,8 +95,7 @@ function loadGUI() { gui.width = 400; } - //add save settings ability (try not to use localstorage) - gui.remember(settings); + // gui.remember(settings); //get object keys var keys = _.keys(settings); @@ -139,7 +138,7 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); - gui.add(settings, 'saveParticleSettings'); + gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); @@ -412,6 +411,20 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } +function importSettings(incomingSettings) { + var importedSettings = JSON.parse(incomingSettings); + var keys = _.keys(importedSettings); + + //for each key... + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return + } + settings[key] = importedSettings[key]; + }) +} + function showPreselectedPrompt() { window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); From 7c6846c260b89f52ecc34aba67b52d0703152a9a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 13:09:41 -0700 Subject: [PATCH 330/418] add lifetime and tag arguments to actions --- examples/controllers/handControllerGrab.js | 7 ++- examples/grab.js | 6 +- interface/src/InterfaceActionFactory.cpp | 7 +++ interface/src/avatar/AvatarActionHold.cpp | 5 +- .../entities/src/EntityActionInterface.h | 2 + libraries/physics/src/ObjectAction.cpp | 57 +++++++++++++++++++ libraries/physics/src/ObjectAction.h | 12 ++-- libraries/physics/src/ObjectActionOffset.cpp | 13 ++++- libraries/physics/src/ObjectActionSpring.cpp | 11 +++- 9 files changed, 106 insertions(+), 14 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 388c042285..144500e4de 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -324,7 +324,9 @@ function MyController(hand, triggerAction) { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: "grab", + lifetime: 5 }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; @@ -424,7 +426,8 @@ function MyController(hand, triggerAction) { targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + lifetime: 5 }); }; diff --git a/examples/grab.js b/examples/grab.js index 05bcf128e2..15bab17f20 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -288,7 +288,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {}; + var actionArgs = {tag: "grab", lifetime: 5}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -303,7 +303,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: "grab", lifetime: 5}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -327,7 +327,7 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: "grab", lifetime: 5}; beacon.updatePosition(this.targetPosition); } diff --git a/interface/src/InterfaceActionFactory.cpp b/interface/src/InterfaceActionFactory.cpp index dca1015ecc..2879c19eaa 100644 --- a/interface/src/InterfaceActionFactory.cpp +++ b/interface/src/InterfaceActionFactory.cpp @@ -43,6 +43,9 @@ EntityActionPointer InterfaceActionFactory::factory(EntityActionType type, if (action) { bool ok = action->updateArguments(arguments); if (ok) { + if (action->lifetimeIsOver()) { + return nullptr; + } return action; } } @@ -63,5 +66,9 @@ EntityActionPointer InterfaceActionFactory::factoryBA(EntityItemPointer ownerEnt if (action) { action->deserialize(data); } + if (action->lifetimeIsOver()) { + return nullptr; + } + return action; } diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 4ecdb692ac..1fa50b79fd 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -84,6 +84,9 @@ void AvatarActionHold::updateActionWorker(float deltaTimeStep) { bool AvatarActionHold::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } bool ok = true; glm::vec3 relativePosition = EntityActionInterface::extractVec3Argument("hold", arguments, "relativePosition", ok, false); @@ -134,7 +137,7 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { QVariantMap AvatarActionHold::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&]{ if (!_mine) { arguments = ObjectActionSpring::getArguments(); diff --git a/libraries/entities/src/EntityActionInterface.h b/libraries/entities/src/EntityActionInterface.h index a4f1c8ea15..e61019c98c 100644 --- a/libraries/entities/src/EntityActionInterface.h +++ b/libraries/entities/src/EntityActionInterface.h @@ -46,6 +46,8 @@ public: static EntityActionType actionTypeFromString(QString actionTypeString); static QString actionTypeToString(EntityActionType actionType); + virtual bool lifetimeIsOver() { return false; } + protected: virtual glm::vec3 getPosition() = 0; virtual void setPosition(glm::vec3 position) = 0; diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 5205e08c62..8c382f8dad 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -30,6 +30,18 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta dynamicsWorld->removeAction(this); return; } + + if (_expires > 0.0f) { + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (now > _expires) { + EntityItemPointer ownerEntity = _ownerEntity.lock(); + _active = false; + if (ownerEntity) { + ownerEntity->removeAction(nullptr, getID()); + } + } + } + if (!_active) { return; } @@ -37,6 +49,40 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta updateActionWorker(deltaTimeStep); } +bool ObjectAction::updateArguments(QVariantMap arguments) { + bool lifetimeSet = true; + float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); + if (lifetimeSet) { + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + _expires = now + lifetime; + } else { + _expires = 0.0f; + } + + bool tagSet = true; + QString tag = EntityActionInterface::extractStringArgument("action", arguments, "tag", tagSet, false); + if (tagSet) { + _tag = tag; + } else { + tag = ""; + } + + return true; +} + +QVariantMap ObjectAction::getArguments() { + QVariantMap arguments; + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (_expires == 0.0f) { + arguments["lifetime"] = 0.0f; + } else { + arguments["lifetime"] = _expires - now; + } + arguments["tag"] = _tag; + return arguments; +} + + void ObjectAction::debugDraw(btIDebugDraw* debugDrawer) { } @@ -136,3 +182,14 @@ void ObjectAction::activateBody() { } } +bool ObjectAction::lifetimeIsOver() { + if (_expires == 0.0f) { + return false; + } + + float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (now >= _expires) { + return true; + } + return false; +} diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 4d91d0dbb1..380263577a 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -33,8 +33,8 @@ public: virtual EntityItemWeakPointer getOwnerEntity() const { return _ownerEntity; } virtual void setOwnerEntity(const EntityItemPointer ownerEntity) { _ownerEntity = ownerEntity; } - virtual bool updateArguments(QVariantMap arguments) = 0; - virtual QVariantMap getArguments() = 0; + virtual bool updateArguments(QVariantMap arguments); + virtual QVariantMap getArguments(); // this is called from updateAction and should be overridden by subclasses virtual void updateActionWorker(float deltaTimeStep) = 0; @@ -46,6 +46,8 @@ public: virtual QByteArray serialize() const = 0; virtual void deserialize(QByteArray serializedArguments) = 0; + virtual bool lifetimeIsOver(); + protected: virtual btRigidBody* getRigidBody(); @@ -59,11 +61,11 @@ protected: virtual void setAngularVelocity(glm::vec3 angularVelocity); virtual void activateBody(); -private: - -protected: bool _active; EntityItemWeakPointer _ownerEntity; + + float _expires; // in seconds since epoch + QString _tag; }; #endif // hifi_ObjectAction_h diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index 2c1b391ba5..448ec34689 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -80,6 +80,9 @@ void ObjectActionOffset::updateActionWorker(btScalar deltaTimeStep) { bool ObjectActionOffset::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } bool ok = true; glm::vec3 pointToOffsetFrom = EntityActionInterface::extractVec3Argument("offset action", arguments, "pointToOffsetFrom", ok, true); @@ -90,7 +93,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { ok = true; float linearTimeScale = EntityActionInterface::extractFloatArgument("offset action", arguments, "linearTimeScale", ok, false); - if (!ok) { + if (!ok) { linearTimeScale = _linearTimeScale; } @@ -119,7 +122,7 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { } QVariantMap ObjectActionOffset::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&] { arguments["pointToOffsetFrom"] = glmToQMap(_pointToOffsetFrom); arguments["linearTimeScale"] = _linearTimeScale; @@ -140,6 +143,9 @@ QByteArray ObjectActionOffset::serialize() const { dataStream << _linearTimeScale; dataStream << _positionalTargetSet; + dataStream << _expires; + dataStream << _tag; + return ba; } @@ -165,5 +171,8 @@ void ObjectActionOffset::deserialize(QByteArray serializedArguments) { dataStream >> _linearTimeScale; dataStream >> _positionalTargetSet; + dataStream >> _expires; + dataStream >> _tag; + _active = true; } diff --git a/libraries/physics/src/ObjectActionSpring.cpp b/libraries/physics/src/ObjectActionSpring.cpp index d163933299..7d0bab5143 100644 --- a/libraries/physics/src/ObjectActionSpring.cpp +++ b/libraries/physics/src/ObjectActionSpring.cpp @@ -109,6 +109,9 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) { const float MIN_TIMESCALE = 0.1f; bool ObjectActionSpring::updateArguments(QVariantMap arguments) { + if (!ObjectAction::updateArguments(arguments)) { + return false; + } // targets are required, spring-constants are optional bool ok = true; glm::vec3 positionalTarget = @@ -155,7 +158,7 @@ bool ObjectActionSpring::updateArguments(QVariantMap arguments) { } QVariantMap ObjectActionSpring::getArguments() { - QVariantMap arguments; + QVariantMap arguments = ObjectAction::getArguments(); withReadLock([&] { arguments["linearTimeScale"] = _linearTimeScale; arguments["targetPosition"] = glmToQMap(_positionalTarget); @@ -182,6 +185,9 @@ QByteArray ObjectActionSpring::serialize() const { dataStream << _angularTimeScale; dataStream << _rotationalTargetSet; + dataStream << _expires; + dataStream << _tag; + return serializedActionArguments; } @@ -210,5 +216,8 @@ void ObjectActionSpring::deserialize(QByteArray serializedArguments) { dataStream >> _angularTimeScale; dataStream >> _rotationalTargetSet; + dataStream >> _expires; + dataStream >> _tag; + _active = true; } From b34ea6ded499a401f92057b1b7ac5936ba82d52f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 13:46:23 -0700 Subject: [PATCH 331/418] store action lifetime as an expires integer --- examples/grab.js | 37 +++++++++++++++++++++++--- libraries/physics/src/ObjectAction.cpp | 20 +++++++------- libraries/physics/src/ObjectAction.h | 2 +- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 15bab17f20..52b2a66546 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -15,6 +15,33 @@ var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; +if (typeof String.prototype.startsWith != 'function') { + // see below for better implementation! + String.prototype.startsWith = function (str){ + return this.indexOf(str) === 0; + }; +} + +function getTag() { + return "grab-" + MyAvatar.sessionUUID; +} + +function entityIsGrabbedByOther(entityID) { + var actionIDs = Entities.getActionIDs(entityID); + for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { + var actionID = actionIDs[actionIndex]; + var actionArguments = Entities.getActionArguments(entityID, actionID); + var tag = actionArguments["tag"]; + if (tag == getTag()) { + continue; + } + if (tag.startsWith("grab-")) { + return true; + } + } + return false; +} + // helper function function mouseIntersectionWithPlane(pointOnPlane, planeNormal, event, maxDistance) { var cameraPosition = Camera.getPosition(); @@ -288,7 +315,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {tag: "grab", lifetime: 5}; + var actionArgs = {tag: getTag(), lifetime: 5}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -303,7 +330,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: "grab", lifetime: 5}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: 5}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -327,13 +354,15 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: "grab", lifetime: 5}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: 5}; beacon.updatePosition(this.targetPosition); } if (!this.actionID) { - this.actionID = Entities.addAction("spring", this.entityID, actionArgs); + if (!entityIsGrabbedByOther(this.entityID)) { + this.actionID = Entities.addAction("spring", this.entityID, actionArgs); + } } else { Entities.updateAction(this.entityID, this.actionID, actionArgs); } diff --git a/libraries/physics/src/ObjectAction.cpp b/libraries/physics/src/ObjectAction.cpp index 8c382f8dad..82395c21cf 100644 --- a/libraries/physics/src/ObjectAction.cpp +++ b/libraries/physics/src/ObjectAction.cpp @@ -31,8 +31,8 @@ void ObjectAction::updateAction(btCollisionWorld* collisionWorld, btScalar delta return; } - if (_expires > 0.0f) { - float now = (float)usecTimestampNow() / USECS_PER_SECOND; + if (_expires > 0) { + quint64 now = usecTimestampNow(); if (now > _expires) { EntityItemPointer ownerEntity = _ownerEntity.lock(); _active = false; @@ -53,10 +53,10 @@ bool ObjectAction::updateArguments(QVariantMap arguments) { bool lifetimeSet = true; float lifetime = EntityActionInterface::extractFloatArgument("action", arguments, "lifetime", lifetimeSet, false); if (lifetimeSet) { - float now = (float)usecTimestampNow() / USECS_PER_SECOND; - _expires = now + lifetime; + quint64 now = usecTimestampNow(); + _expires = now + (quint64)(lifetime * USECS_PER_SECOND); } else { - _expires = 0.0f; + _expires = 0; } bool tagSet = true; @@ -72,11 +72,11 @@ bool ObjectAction::updateArguments(QVariantMap arguments) { QVariantMap ObjectAction::getArguments() { QVariantMap arguments; - float now = (float)usecTimestampNow() / USECS_PER_SECOND; - if (_expires == 0.0f) { + if (_expires == 0) { arguments["lifetime"] = 0.0f; } else { - arguments["lifetime"] = _expires - now; + quint64 now = usecTimestampNow(); + arguments["lifetime"] = (float)(_expires - now) / (float)USECS_PER_SECOND; } arguments["tag"] = _tag; return arguments; @@ -183,11 +183,11 @@ void ObjectAction::activateBody() { } bool ObjectAction::lifetimeIsOver() { - if (_expires == 0.0f) { + if (_expires == 0) { return false; } - float now = (float)usecTimestampNow() / USECS_PER_SECOND; + quint64 now = usecTimestampNow(); if (now >= _expires) { return true; } diff --git a/libraries/physics/src/ObjectAction.h b/libraries/physics/src/ObjectAction.h index 380263577a..5c29ac9892 100644 --- a/libraries/physics/src/ObjectAction.h +++ b/libraries/physics/src/ObjectAction.h @@ -64,7 +64,7 @@ protected: bool _active; EntityItemWeakPointer _ownerEntity; - float _expires; // in seconds since epoch + quint64 _expires; // in seconds since epoch QString _tag; }; From f746a970de5c849d5c687ca9ddb1c3c1a015c380 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:03:10 -0700 Subject: [PATCH 332/418] don't grab something if someone else is already grabbing it --- examples/controllers/handControllerGrab.js | 69 ++++++++++++++++------ 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 144500e4de..6bd1949cd3 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -91,6 +91,27 @@ var currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; var noCollisionsCount = 0; // how many hands want collisions disabled? +function getTag() { + return "grab-" + MyAvatar.sessionUUID; +} + +function entityIsGrabbedByOther(entityID) { + var actionIDs = Entities.getActionIDs(entityID); + for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { + var actionID = actionIDs[actionIndex]; + var actionArguments = Entities.getActionArguments(entityID, actionID); + var tag = actionArguments["tag"]; + if (tag == getTag()) { + continue; + } + if (tag.startsWith("grab-")) { + return true; + } + } + return false; +} + + function MyController(hand, triggerAction) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -320,14 +341,17 @@ function MyController(hand, triggerAction) { this.handPreviousPosition = handControllerPosition; this.handPreviousRotation = handRotation; - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - tag: "grab", - lifetime: 5 - }); + this.actionID = NULL_ACTION_ID; + if (!entityIsGrabbedByOther(this.grabbedEntity)) { + this.actionID = Entities.addAction("spring", this.grabbedEntity, { + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: getTag(), + lifetime: 5 + }); + } if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } @@ -392,11 +416,11 @@ function MyController(hand, triggerAction) { var handMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, handToAvatar), handToAvatar); var objectMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, objectToAvatar), objectToAvatar); this.currentAvatarOrientation = currentOrientation; - + // how far did hand move this timestep? var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; - + // magnify the hand movement but not the change from avatar movement & rotation handMoved = Vec3.subtract(handMoved, avatarDeltaPosition); handMoved = Vec3.subtract(handMoved, handMovementFromTurning); @@ -439,7 +463,7 @@ function MyController(hand, triggerAction) { if (this.triggerSmoothedReleased()) { // HACK -- until we have collision groups, don't allow held object to collide with avatar this.revertAvatarCollisions(); - + this.state = STATE_RELEASE; return; } @@ -460,12 +484,17 @@ function MyController(hand, triggerAction) { var offset = Vec3.subtract(currentObjectPosition, handPosition); var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation - }); + this.actionID = NULL_ACTION_ID; + if (!entityIsGrabbedByOther(this.grabbedEntity)) { + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: offsetPosition, + relativeRotation: offsetRotation, + tag: getTag(), + lifetime: 5 + }); + } if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { @@ -488,7 +517,7 @@ function MyController(hand, triggerAction) { if (this.triggerSmoothedReleased()) { // HACK -- until we have collision groups, don't allow held object to collide with avatar this.revertAvatarCollisions(); - + this.state = STATE_RELEASE; return; } @@ -498,7 +527,7 @@ function MyController(hand, triggerAction) { // object's actual held offset is an idea intended to make it easier to throw things: // Because we might catch something or transfer it between hands without a good idea // of it's actual offset, let's try imparting a velocity which is at a fixed radius - // from the palm. + // from the palm. var handControllerPosition = Controller.getSpatialControlPosition(this.tip); var now = Date.now(); @@ -510,6 +539,8 @@ function MyController(hand, triggerAction) { this.currentHandControllerTipPosition = handControllerPosition; this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); + + Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: 5}); }; this.nearGrabbingNonColliding = function() { From c27766facbcaad439d98127a031a781c23f0efec Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:07:23 -0700 Subject: [PATCH 333/418] move string startswith to utils.js --- examples/grab.js | 8 -------- examples/libraries/utils.js | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 52b2a66546..3a9ce9921d 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -14,14 +14,6 @@ var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be gr var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; - -if (typeof String.prototype.startsWith != 'function') { - // see below for better implementation! - String.prototype.startsWith = function (str){ - return this.indexOf(str) === 0; - }; -} - function getTag() { return "grab-" + MyAvatar.sessionUUID; } diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index f6f635c73a..2ee9bdd5fb 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,3 +179,9 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } + +if (typeof String.prototype.startsWith != 'function') { + String.prototype.startsWith = function (str){ + return this.slice(0, str.length) == str; + }; +} From b417abc3de44acda7caadd4e76b64e88433dd2d3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:16:07 -0700 Subject: [PATCH 334/418] try again on string startswith --- examples/controllers/handControllerGrab.js | 2 +- examples/grab.js | 2 +- examples/libraries/utils.js | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 6bd1949cd3..aaa894a887 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -104,7 +104,7 @@ function entityIsGrabbedByOther(entityID) { if (tag == getTag()) { continue; } - if (tag.startsWith("grab-")) { + if (tag.slice(0, 5) == "grab-") { return true; } } diff --git a/examples/grab.js b/examples/grab.js index 3a9ce9921d..3e0212bbba 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -27,7 +27,7 @@ function entityIsGrabbedByOther(entityID) { if (tag == getTag()) { continue; } - if (tag.startsWith("grab-")) { + if (tag.slice(0, 5) == "grab-") { return true; } } diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index 2ee9bdd5fb..f6f635c73a 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,9 +179,3 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } - -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} From 9cf49597a69bba1dee45d0a14d01d877990c3cd9 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 14:16:41 -0700 Subject: [PATCH 335/418] fix possible crash from null coming from _sentPackets --- libraries/networking/src/SentPacketHistory.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/SentPacketHistory.cpp b/libraries/networking/src/SentPacketHistory.cpp index 14b4677fc3..fbb7eff41a 100644 --- a/libraries/networking/src/SentPacketHistory.cpp +++ b/libraries/networking/src/SentPacketHistory.cpp @@ -51,5 +51,9 @@ const NLPacket* SentPacketHistory::getPacket(uint16_t sequenceNumber) const { } QReadLocker locker(&_packetsLock); - return _sentPackets.get(seqDiff)->get(); + auto packet = _sentPackets.get(seqDiff); + if (packet) { + return packet->get(); + } + return nullptr; } From dd0a16df047d9472088c469defe6c7d486f6a803 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 14:19:59 -0700 Subject: [PATCH 336/418] don't leave search state if we intersect something that someone else is already grabbing --- examples/actionInspector.js | 4 ++-- examples/controllers/handControllerGrab.js | 21 ++++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/actionInspector.js b/examples/actionInspector.js index 7e342b9e11..934120ddf6 100644 --- a/examples/actionInspector.js +++ b/examples/actionInspector.js @@ -49,8 +49,8 @@ function actionArgumentsToString(actionArguments) { function updateOverlay(entityID, actionText) { - var properties = Entities.getEntityProperties(entityID, ["position"]); - var position = Vec3.sum(properties.position, {x:0, y:1, z:0}); + var properties = Entities.getEntityProperties(entityID, ["position", "dimensions"]); + var position = Vec3.sum(properties.position, {x:0, y:properties.dimensions.y, z:0}); // print("position: " + vec3toStr(position) + " " + actionText); if (entityID in overlays) { var overlay = overlays[entityID]; diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index aaa894a887..4037ae66dc 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -273,7 +273,8 @@ function MyController(hand, triggerAction) { var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0) { + intersection.properties.locked === 0 && + !entityIsGrabbedByOther(intersection.entityID)) { // the ray is intersecting something we can move. var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); @@ -342,16 +343,14 @@ function MyController(hand, triggerAction) { this.handPreviousRotation = handRotation; this.actionID = NULL_ACTION_ID; - if (!entityIsGrabbedByOther(this.grabbedEntity)) { - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - tag: getTag(), - lifetime: 5 - }); - } + this.actionID = Entities.addAction("spring", this.grabbedEntity, { + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + tag: getTag(), + lifetime: 5 + }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } From 3cdb4e7186fc9bb73f897ad38ddfc68c115b776f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 14:23:11 -0700 Subject: [PATCH 337/418] importing --- examples/particle_explorer/index.html | 22 +++++++++ examples/particle_explorer/main.js | 69 +++++++++++++++++---------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 1772423d02..06ffc0390b 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -24,10 +24,32 @@ width:100%; height:100%; } + +.importer{ + margin:5px; + width:100%; +} + +::-webkit-input-placeholder { + + margin:4px; + font-family: Helvetica +} + +#importer-input{ + width:90%; + line-height: 2; + margin-left:5%; +} + +
    + +
    + \ No newline at end of file diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 4db3f4b9e9..9ac556f961 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -15,7 +15,11 @@ var Settings = function() { this.exportSettings = function() { showPreselectedPrompt(); + }; + this.importSettings = function() { + importSettings(); } + return; }; @@ -27,6 +31,8 @@ var updateInterval; var UPDATE_ALL_FREQUENCY = 1000; var keysToIgnore = [ + 'importSettings', + 'exportSettings', 'script', 'visible', 'locked', @@ -92,7 +98,7 @@ function loadGUI() { if (gui.autoPlace === false) { var customContainer = document.getElementById('my-gui-container'); customContainer.appendChild(gui.domElement); - gui.width = 400; + gui.width = 500; } // gui.remember(settings); @@ -105,7 +111,7 @@ function loadGUI() { var shouldIgnore = _.contains(keysToIgnore, key); if (shouldIgnore) { - return + return; } var subKeys = _.keys(settings[key]); var hasX = _.contains(subKeys, 'x'); @@ -120,7 +126,7 @@ function loadGUI() { vec3Keys.push(key); } else if (hasX && hasY && hasZ && hasW) { // console.log(key + " is a quaternion"); - quatKeys.push(key) + quatKeys.push(key); } else if (hasRed || hasGreen || hasBlue) { // console.log(key + " is a color"); colorKeys.push(key); @@ -138,22 +144,20 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); + gui.add(settings, 'importSettings'); gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); - // showParticleSettings(); - // showPreselectedPrompt(); } function addIndividualKeys() { _.each(individualKeys, function(key) { - var controller = gui.add(settings, key) - //need to fix not being able to input values if constantly listening - //.listen(); + var controller = gui.add(settings, key); + //need to fix not being able to input values if constantly listening + //.listen(); // keep track of our controller controllers.push(controller); @@ -163,19 +167,19 @@ function addIndividualKeys() { // Fires on every change, drag, keypress, etc. writeDataToInterface(this.property, value); }); - }) + }); } function addFolders() { _.each(vec3Keys, function(key) { createVec3Folder(key); - }) + }); _.each(quatKeys, function(key) { createQuatFolder(key); - }) + }); _.each(colorKeys, function(key) { createColorFolder(key); - }) + }); } function createVec3Folder(category) { @@ -395,7 +399,6 @@ function showParticleSettings() { codeBlock.innerHTML = prepareSettingsForExport(); } - function prepareSettingsForExport() { var keys = _.keys(settings); var exportSettings = {}; @@ -403,7 +406,7 @@ function prepareSettingsForExport() { _.each(keys, function(key) { var shouldIgnore = _.contains(keysToIgnore, key); if (shouldIgnore) { - return + return; } exportSettings[key] = settings[key]; @@ -411,20 +414,34 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } -function importSettings(incomingSettings) { - var importedSettings = JSON.parse(incomingSettings); - var keys = _.keys(importedSettings); +function importSettings() { + var importInput = document.getElementById('importer-input'); + console.log('import value' + importInput.value) + try { + var importedSettings = JSON.parse(importInput.value); + // importedSettings = importInput.value; + var keys = _.keys(importedSettings); + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return; + } + settings[key] = importedSettings[key]; + }); + writeVec3ToInterface(settings); + manuallyUpdateDisplay(); + } catch (e) { + alert('Not properly formatted JSON'); //error in the above string(in this case,yes)! + } - //for each key... - _.each(keys, function(key) { - var shouldIgnore = _.contains(keysToIgnore, key); - if (shouldIgnore) { - return - } - settings[key] = importedSettings[key]; - }) } +function handleInputKeyPress(e) { + if (e.keyCode === 13) { + importSettings(); + } + return false; +} function showPreselectedPrompt() { window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); From 0063eee4a07b9d39c5993b4fd11cd0a0d3fc89d3 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 30 Sep 2015 14:47:12 -0700 Subject: [PATCH 338/418] Fix issue with nackPacketList being accessed after being moved --- .../octree/OctreeInboundPacketProcessor.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index 4ae07042e8..cb94990037 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -238,7 +238,6 @@ int OctreeInboundPacketProcessor::sendNackPackets() { return 0; } - auto nackPacketList = NLPacketList::create(_myServer->getMyEditNackType()); auto nodeList = DependencyManager::get(); int packetsSent = 0; @@ -272,18 +271,19 @@ int OctreeInboundPacketProcessor::sendNackPackets() { auto it = missingSequenceNumbers.constBegin(); - while (it != missingSequenceNumbers.constEnd()) { - unsigned short int sequenceNumber = *it; - nackPacketList->writePrimitive(sequenceNumber); - ++it; - } - - - if (nackPacketList->getNumPackets()) { + if (it != missingSequenceNumbers.constEnd()) { + auto nackPacketList = NLPacketList::create(_myServer->getMyEditNackType()); + + while (it != missingSequenceNumbers.constEnd()) { + unsigned short int sequenceNumber = *it; + nackPacketList->writePrimitive(sequenceNumber); + ++it; + } + qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID; - + packetsSent += nackPacketList->getNumPackets(); - + // send the list of nack packets nodeList->sendPacketList(std::move(nackPacketList), *destinationNode); } From 34dc8bdbcb8de07f6e6726efefd9462c67f241d5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 15:34:35 -0700 Subject: [PATCH 339/418] fix possible crash in agent --- assignment-client/src/Agent.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 157154606f..47db78b5e4 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -364,10 +364,14 @@ void Agent::processAgentAvatarAndAudio(float deltaTime) { } void Agent::aboutToFinish() { - _scriptEngine->stop(); + if (_scriptEngine) { + _scriptEngine->stop(); + } - _pingTimer->stop(); - delete _pingTimer; + if (_pingTimer) { + _pingTimer->stop(); + delete _pingTimer; + } // our entity tree is going to go away so tell that to the EntityScriptingInterface DependencyManager::get()->setEntityTree(NULL); From 75e858cd1314009181c21c0764996dbf266f9ccf Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 15:54:03 -0700 Subject: [PATCH 340/418] Putting together the stencil buffer for opaque vs background and using it for the backgroud render items --- interface/src/Stars.cpp | 2 ++ libraries/gpu/src/gpu/GLBackendState.cpp | 5 +-- libraries/gpu/src/gpu/State.h | 6 ++-- libraries/model/src/model/Skybox.cpp | 1 + .../src/procedural/ProceduralSkybox.cpp | 3 +- libraries/render-utils/src/Environment.cpp | 3 +- .../render-utils/src/FramebufferCache.cpp | 14 ++++----- libraries/render-utils/src/FramebufferCache.h | 4 +-- .../render-utils/src/RenderDeferredTask.cpp | 31 ++++++++++--------- .../render-utils/src/drawOpaqueStencil.slf | 14 +++------ 10 files changed, 44 insertions(+), 39 deletions(-) diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 4af1a26612..6145529b52 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -141,6 +141,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _gridPipeline.reset(gpu::Pipeline::create(program, state)); } @@ -152,6 +153,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setAntialiasedLineEnable(true); // line smoothing also smooth points state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _starsPipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 9fdcbc0870..feba6e6853 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -655,11 +655,12 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilFuncSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - glStencilFuncSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index 5500f20e06..7740506bce 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -143,11 +143,11 @@ public: static const int PASS_OP_OFFSET = 12; uint16 _functionAndOperations; - uint8 _reference = 0; + int8 _reference = 0; uint8 _readMask = 0xff; public: - StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : + StencilTest(int8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), _reference(reference), _readMask(readMask) {} @@ -157,7 +157,7 @@ public: StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); } StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); } - uint8 getReference() const { return _reference; } + int8 getReference() const { return _reference; } uint8 getReadMask() const { return _readMask; } int32 getRaw() const { return *(reinterpret_cast(this)); } diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e27a0d25ce..944d16a6dd 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -89,6 +89,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 8d34f0e7e5..f69e0575de 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -32,7 +32,8 @@ void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) { if (_procedural) { _procedural->_vertexSource = ProceduralSkybox_vert; _procedural->_fragmentSource = ProceduralSkybox_frag; - // No pipeline state customization + // Adjust the pipeline state for background using the stencil test + _procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 365fbdb16a..acb149a3cc 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -63,7 +63,8 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra state->setCullMode(gpu::State::CULL_NONE); // state->setDepthTest(false); - state->setDepthTest(true, false, gpu::LESS_EQUAL); + // state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index eb154f77c9..cd81a21f9a 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,7 +35,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _primaryFramebufferFull.reset(); _primaryFramebufferDepthColor.reset(); - _primaryFramebufferDepthStencilColor.reset(); + _primaryFramebufferStencilColor.reset(); _primaryDepthTexture.reset(); _primaryStencilTexture.reset(); _primaryColorTexture.reset(); @@ -49,7 +49,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _primaryFramebufferDepthStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebufferStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); auto width = _frameBufferSize.width(); @@ -66,7 +66,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); - _primaryFramebufferDepthStencilColor->setRenderBuffer(0, _primaryColorTexture); + _primaryFramebufferStencilColor->setRenderBuffer(0, _primaryColorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); @@ -78,7 +78,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - _primaryFramebufferDepthStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); + _primaryFramebufferStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); @@ -99,11 +99,11 @@ gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { return _primaryFramebufferDepthColor; } -gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthStencilColor() { - if (!_primaryFramebufferDepthStencilColor) { +gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferStencilColor() { + if (!_primaryFramebufferStencilColor) { createPrimaryFramebuffer(); } - return _primaryFramebufferDepthStencilColor; + return _primaryFramebufferStencilColor; } gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index baca07af24..8951ceee80 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -31,7 +31,7 @@ public: /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); - gpu::FramebufferPointer getPrimaryFramebufferDepthStencilColor(); + gpu::FramebufferPointer getPrimaryFramebufferStencilColor(); gpu::TexturePointer getPrimaryDepthTexture(); gpu::TexturePointer getPrimaryStencilTexture(); @@ -60,7 +60,7 @@ private: gpu::FramebufferPointer _primaryFramebufferFull; gpu::FramebufferPointer _primaryFramebufferDepthColor; - gpu::FramebufferPointer _primaryFramebufferDepthStencilColor; + gpu::FramebufferPointer _primaryFramebufferStencilColor; gpu::TexturePointer _primaryDepthTexture; gpu::TexturePointer _primaryStencilTexture; gpu::TexturePointer _primaryColorTexture; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 71bc41e6b6..e16544f5cd 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -301,12 +301,18 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { + const gpu::int8 STENCIL_OPAQUE = 1; auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + + gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); + state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); } @@ -322,23 +328,20 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); + + batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - - batch.enableStereo(false); + batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + Transform modelMat; + batch.setModelTransform(modelMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -369,13 +372,13 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - // auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFboColorStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); - batch.setFramebuffer(primaryFboColorDepthStencil); - batch.enableSkybox(true); + + batch.setFramebuffer(primaryFboColorStencil); + batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index dae3e56c4d..883154c624 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -12,22 +12,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - in vec2 varTexCoord0; out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { + // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - float depth = texture(depthTexture, varTexCoord0).r; - - if (depth >= 0.9) { - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + float depth = texture(depthTexture, varTexCoord0.xy).r; + outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + if (depth < 1.0) { + outFragColor = vec4(0.0, 1.0, 0.0, 1.0); } else { discard; } From 42d90457707248eff86e10b15626d3bf42387005 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 16:02:33 -0700 Subject: [PATCH 341/418] possible fix for crashing agents acting like avatars --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 47db78b5e4..4438782ae5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -364,6 +364,7 @@ void Agent::processAgentAvatarAndAudio(float deltaTime) { } void Agent::aboutToFinish() { + setIsAvatar(false);// will stop timers for sending billboards and identity packets if (_scriptEngine) { _scriptEngine->stop(); } From 4e057e5adafcbc47b48cdc724d9d8a46c2c14064 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 16:03:54 -0700 Subject: [PATCH 342/418] increase action lifetime to be more forgiving of clock skew. remove code that makes avatar a ghost while holding something --- examples/controllers/handControllerGrab.js | 56 ++-------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index aaa894a887..cf2562af62 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -66,6 +66,7 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var startTime = Date.now(); var LIFETIME = 10; +var ACTION_LIFETIME = 120; // 2 minutes // states for the state machine var STATE_OFF = 0; @@ -81,16 +82,6 @@ var STATE_RELEASE = 8; var GRAB_USER_DATA_KEY = "grabKey"; var GRABBABLE_DATA_KEY = "grabbableKey"; -// HACK -- until we have collision groups, don't allow held object to collide with avatar -var AVATAR_COLLISIONS_MENU_ITEM = "Enable avatar collisions"; - - -// HACK -- until we have collision groups, don't allow held object to collide with avatar -var initialAvatarCollisionsMenu = Menu.isOptionChecked(AVATAR_COLLISIONS_MENU_ITEM); -var currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; -var noCollisionsCount = 0; // how many hands want collisions disabled? - - function getTag() { return "grab-" + MyAvatar.sessionUUID; } @@ -173,28 +164,6 @@ function MyController(hand, triggerAction) { } }; - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions = function() { - noCollisionsCount += 1; - if (currentAvatarCollisionsMenu != false) { - currentAvatarCollisionsMenu = false; - Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, false); - MyAvatar.updateMotionBehaviorFromMenu(); - } - } - - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions = function() { - noCollisionsCount -= 1; - if (noCollisionsCount < 1) { - if (currentAvatarCollisionsMenu != initialAvatarCollisionsMenu) { - currentAvatarCollisionsMenu = initialAvatarCollisionsMenu; - Menu.setIsOptionChecked(AVATAR_COLLISIONS_MENU_ITEM, initialAvatarCollisionsMenu); - MyAvatar.updateMotionBehaviorFromMenu(); - } - } - } - this.lineOn = function(closePoint, farPoint, color) { // draw a line if (this.pointer === null) { @@ -327,9 +296,6 @@ function MyController(hand, triggerAction) { this.distanceHolding = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions(); - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); @@ -349,7 +315,7 @@ function MyController(hand, triggerAction) { targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, tag: getTag(), - lifetime: 5 + lifetime: ACTION_LIFETIME }); } if (this.actionID === NULL_ACTION_ID) { @@ -374,9 +340,6 @@ function MyController(hand, triggerAction) { this.continueDistanceHolding = function() { if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -451,19 +414,13 @@ function MyController(hand, triggerAction) { linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - lifetime: 5 + lifetime: ACTION_LIFETIME }); }; this.nearGrabbing = function() { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.disableAvatarCollisions(); - if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -492,7 +449,7 @@ function MyController(hand, triggerAction) { relativePosition: offsetPosition, relativeRotation: offsetRotation, tag: getTag(), - lifetime: 5 + lifetime: ACTION_LIFETIME }); } if (this.actionID === NULL_ACTION_ID) { @@ -515,9 +472,6 @@ function MyController(hand, triggerAction) { this.continueNearGrabbing = function() { if (this.triggerSmoothedReleased()) { - // HACK -- until we have collision groups, don't allow held object to collide with avatar - this.revertAvatarCollisions(); - this.state = STATE_RELEASE; return; } @@ -540,7 +494,7 @@ function MyController(hand, triggerAction) { this.currentObjectTime = now; Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: 5}); + Entities.updateAction(this.grabbedEntity, this.actionID, {lifetime: ACTION_LIFETIME}); }; this.nearGrabbingNonColliding = function() { From 91965db5abc61ce3d4a8601bc9ecab2451f3746b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 30 Sep 2015 16:07:22 -0700 Subject: [PATCH 343/418] increase action lifetime to be more forgiving of clock skew. remove code that makes avatar a ghost while holding something --- examples/grab.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/grab.js b/examples/grab.js index 3e0212bbba..43a5ed220b 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -13,6 +13,7 @@ var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be grabbed var ZERO_VEC3 = {x: 0, y: 0, z: 0}; var IDENTITY_QUAT = {x: 0, y: 0, z: 0, w: 0}; +var ACTION_LIFETIME = 120; // 2 minutes function getTag() { return "grab-" + MyAvatar.sessionUUID; @@ -307,7 +308,7 @@ Grabber.prototype.moveEvent = function(event) { } this.currentPosition = entityProperties.position; - var actionArgs = {tag: getTag(), lifetime: 5}; + var actionArgs = {tag: getTag(), lifetime: ACTION_LIFETIME}; if (this.mode === "rotate") { var drag = mouse.getDrag(); @@ -322,7 +323,7 @@ Grabber.prototype.moveEvent = function(event) { // var qZero = entityProperties.rotation; //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: 5}; + actionArgs = {targetRotation: this.lastRotation, angularTimeScale: 0.1, tag: getTag(), lifetime: ACTION_LIFETIME}; } else { var newPointOnPlane; if (this.mode === "verticalCylinder") { @@ -346,7 +347,7 @@ Grabber.prototype.moveEvent = function(event) { } } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: 5}; + actionArgs = {targetPosition: this.targetPosition, linearTimeScale: 0.1, tag: getTag(), lifetime: ACTION_LIFETIME}; beacon.updatePosition(this.targetPosition); } From c55d627e9bd33f302d4e33a1c323dfb07d2343ad Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 16:12:27 -0700 Subject: [PATCH 344/418] Different model, different sounds, release interval --- .../toys/ping_pong_gun/createPingPongGun.js | 6 +-- examples/toys/ping_pong_gun/pingPongGun.js | 54 ++++++++++++------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index 1bf0415ebd..d8509d8a63 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -31,9 +31,9 @@ var pingPongGun = Entities.addEntity({ script: scriptURL, position: center, dimensions: { - x: 0.1, - y: 0.06, - z: 0.03 + x:0.67, + y: 0.14, + z: 0.09 }, collisionsWillMove: true, }); diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index da7a4a6d28..0a589fb3fb 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -13,8 +13,7 @@ Script.include("../../libraries/utils.js"); - var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/flashlight_on.wav'; - + var SHOOTING_SOUND_URL = 'http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav'; function PingPongGun() { return; @@ -22,20 +21,36 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.08; - var GUN_TIP_UP_OFFSET = 0.020; - var GUN_FORCE = 5; + var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_UP_OFFSET = 0.040; + var GUN_FORCE = 15; + var BALL_RESTITUTION = 0.6; + var BALL_LINEAR_DAMPING = 0.4; var BALL_GRAVITY = { x: 0, - y: -1, + y: -9.8, z: 0 }; + var BALL_DIMENSIONS = { + x: 0.04, + y: 0.04, + z: 0.04 + } + + + var BALL_COLOR = { + red: 255, + green: 255, + blue: 255 + } + PingPongGun.prototype = { hand: null, whichHand: null, gunTipPosition: null, canShoot: false, + canShootTimeout: null, setRightHand: function() { this.hand = 'RIGHT'; }, @@ -53,16 +68,23 @@ }, continueNearGrab: function() { + if (this.whichHand === null) { //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten this.setWhichHand(); } else { + if (this.canShootTimeout !== null) { + Script.clearTimeout(this.canShootTimeout); + } this.checkTriggerPressure(this.whichHand); } }, releaseGrab: function() { - this.canShoot = false; + var _t = this; + this.canShootTimeout = Script.setTimeout(function() { + _t.canShoot = false; + }, 250) }, checkTriggerPressure: function(gunHand) { @@ -89,20 +111,12 @@ forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { type: 'Sphere', - color: { - red: 255, - green: 255, - blue: 255 - }, - dimensions: { - x: 0.02, - y: 0.02, - z: 0.02 - }, - linearDamping: 0.2, + color: BALL_COLOR, + dimensions: BALL_DIMENSIONS, + linearDamping: BALL_LINEAR_DAMPING, gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, collisionsWillMove: true, - collisionSoundURL: SHOOTING_SOUND_URL, rotation: gunProperties.rotation, position: this.getGunTipPosition(gunProperties), velocity: forwardVec, @@ -116,7 +130,7 @@ playSoundAtCurrentPosition: function(position) { var audioProperties = { - volume: 0.25, + volume: 0.1, position: position }; From e516281da8c3993be8a702e766145eef0153556a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 16:15:52 -0700 Subject: [PATCH 345/418] Added closePaint script and removed no longer used spray paint scripts --- examples/closePaint.js | 258 ++++++++++++++++++++++++ examples/entityScripts/sprayPaintCan.js | 252 ----------------------- examples/sprayPaintSpawner.js | 41 ---- 3 files changed, 258 insertions(+), 293 deletions(-) create mode 100644 examples/closePaint.js delete mode 100644 examples/entityScripts/sprayPaintCan.js delete mode 100644 examples/sprayPaintSpawner.js diff --git a/examples/closePaint.js b/examples/closePaint.js new file mode 100644 index 0000000000..dc3e567823 --- /dev/null +++ b/examples/closePaint.js @@ -0,0 +1,258 @@ +// +// closePaint.js +// examples +// +// Created by Eric Levina on 9/30/15. +// Copyright 2015 High Fidelity, Inc. +// +// Run this script to be able to paint on entities you are close to, with hydras. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +var RIGHT_HAND = 1; +var LEFT_HAND = 0; + +var MIN_POINT_DISTANCE = 0.01; +var MAX_POINT_DISTANCE = 0.5; + +var SPATIAL_CONTROLLERS_PER_PALM = 2; +var TIP_CONTROLLER_OFFSET = 1; + +var TRIGGER_ON_VALUE = 0.3; + +var MAX_DISTANCE = 10; + +var STROKE_WIDTH = 0.02 +var MAX_POINTS_PER_LINE = 60; + + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); + + + +function MyController(hand, triggerAction) { + this.hand = hand; + this.strokes = []; + this.painting = false; + + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + } else { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + + this.triggerAction = triggerAction; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; + + + this.strokeColor = { + red: 200, + green: 20, + blue: 40 + }; + + this.laserPointer = Overlays.addOverlay("circle3d", { + size: { + x: STROKE_WIDTH / 2, + y: STROKE_WIDTH / 2 + }, + color: this.strokeColor, + solid: true, + position: center + }) + this.triggerValue = 0; + this.prevTriggerValue = 0; + var _this = this; + + + this.update = function() { + this.updateControllerState() + this.search(); + if (this.canPaint === true) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } + }; + + this.paint = function(position, normal) { + // print("POSITION " + position.z) + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if(this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if(this.strokePoints.length === 0) { + localPoint = {x: 0, y: 0, z: 0}; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(normal); + this.strokeWidths.push(STROKE_WIDTH); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position + + } + + this.newStroke = function(position) { + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: this.strokeColor, + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 100 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + + } + + this.updateControllerState = function() { + var triggerValue = Controller.getActionValue(this.triggerAction); + if (triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.squeeze(); + } else if (triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + this.release() + } + + this.prevTriggerValue = triggerValue; + } + + this.squeeze = function() { + this.tryPainting = true; + + } + this.release = function() { + this.painting = false; + this.tryPainting = false; + this.canPaint = false; + this.oldPosition = null; + } + this.search = function() { + + // the trigger is being pressed, do a ray test + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + + + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .001)); + if (this.tryPainting) { + this.canPaint = true; + } + Overlays.editOverlay(this.laserPointer, { + visible: true, + position: displayPoint, + rotation: orientationOf(this.intersection.surfaceNormal) + }); + + } else { + this.hitFail(); + } + } else { + this.hitFail(); + } + }; + + this.hitFail = function() { + this.canPaint = false; + + Overlays.editOverlay(this.laserPointer, { + visible: false + }); + + } + + this.cleanup = function() { + Overlays.deleteOverlay(this.laserPointer); + this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); + } +} + +var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); +var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); + +function update() { + rightController.update(); + leftController.update(); +} + +function cleanup() { + rightController.cleanup(); + leftController.cleanup(); +} + +Script.scriptEnding.connect(cleanup); +Script.update.connect(update); + + +function orientationOf(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} \ No newline at end of file diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js deleted file mode 100644 index 21613bdeb5..0000000000 --- a/examples/entityScripts/sprayPaintCan.js +++ /dev/null @@ -1,252 +0,0 @@ -(function() { - // Script.include("../libraries/utils.js"); - //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge - - Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; - this.userData = {}; - - var TIP_OFFSET_Z = 0.14; - var TIP_OFFSET_Y = 0.04; - - var ZERO_VEC = { - x: 0, - y: 0, - z: 0 - } - - var MAX_POINTS_PER_LINE = 40; - var MIN_POINT_DISTANCE = 0.01; - var STROKE_WIDTH = 0.02; - - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } - } - - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); - } - - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; - var animationSettings = JSON.stringify({ - fps: 30, - loop: true, - firstFrame: 1, - lastFrame: 10000, - running: true - }); - var PI = 3.141593; - var DEG_TO_RAD = PI / 180.0; - - this.paintStream = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - position: this.properties.position, - textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitSpeed: 0, - speedSpread: 0.02, - polarFinish: 2 * DEG_TO_RAD, - emitAcceleration: ZERO_VEC, - emitRate: 100, - particleRadius: 0.01, - color: { - red: 170, - green: 20, - blue: 150 - }, - lifetime: 50, //probably wont be holding longer than this straight - }); - } - - this.letGo = function() { - this.activated = false; - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - } - - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC - }); - } - - this.sprayStream = function() { - var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); - forwardVec = Vec3.normalize(forwardVec); - - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); - position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { - position: position, - emitOrientation: forwardVec, - emitSpeed: 5 - }); - - //Now check for an intersection with an entity - //move forward so ray doesnt intersect with gun - var origin = Vec3.sum(position, forwardVec); - var pickRay = { - origin: origin, - direction: Vec3.multiply(forwardVec, 2) - } - - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects) { - var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation)); - this.paint(intersection.intersection, normal); - } - - - } - - this.paint = function(position, normal) { - if (!this.painting) { - - this.newStroke(position); - this.painting = true; - } - - if (this.strokePoints.length > MAX_POINTS_PER_LINE) { - this.painting = false; - return; - } - - var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, .1)); - - if (this.strokePoints.length > 0 && Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]) < MIN_POINT_DISTANCE) { - //need a minimum distance to avoid binormal NANs - return; - } - - this.strokePoints.push(localPoint); - this.strokeNormals.push(normal); - this.strokeWidths.push(STROKE_WIDTH); - Entities.editEntity(this.currentStroke, { - linePoints: this.strokePoints, - normals: this.strokeNormals, - strokeWidths: this.strokeWidths - }); - - - } - - this.newStroke = function(position) { - this.strokeBasePosition = position; - this.currentStroke = Entities.addEntity({ - position: position, - type: "PolyLine", - color: { - red: randInt(160, 250), - green: randInt(10, 20), - blue: randInt(190, 250) - }, - dimensions: { - x: 50, - y: 50, - z: 50 - }, - lifetime: 100 - }); - this.strokePoints = []; - this.strokeNormals = []; - this.strokeWidths = []; - - this.strokes.push(this.currentStroke); - } - - this.preload = function(entityId) { - this.strokes = []; - this.activated = false; - this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } - } - - - this.unload = function() { - Script.update.disconnect(this.update); - if(this.paintStream) { - Entities.deleteEntity(this.paintStream); - } - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } - Script.update.connect(this.update); -}); - - - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} \ No newline at end of file diff --git a/examples/sprayPaintSpawner.js b/examples/sprayPaintSpawner.js deleted file mode 100644 index 3b9cee6ef4..0000000000 --- a/examples/sprayPaintSpawner.js +++ /dev/null @@ -1,41 +0,0 @@ -// sprayPaintSpawner.js -// -// Created by Eric Levin on 9/3/15 -// Copyright 2015 High Fidelity, Inc. -// -// This is script spwans a spreay paint can model with the sprayPaintCan.js entity script attached -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -//Just temporarily using my own bucket here so others can test the entity. Once PR is tested and merged, then the entity script will appear in its proper place in S3, and I wil switch it -// var scriptURL = "https://hifi-public.s3.amazonaws.com/eric/scripts/sprayPaintCan.js?=v6 "; -var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js?v2"); -var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; - -var sprayCan = Entities.addEntity({ - type: "Model", - name: "spraycan", - modelURL: modelURL, - position: {x: 549.12, y:495.55, z:503.77}, - rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, - collisionsWillMove: true, - shapeType: 'box', - script: scriptURL, - gravity: {x: 0, y: -0.5, z: 0}, - velocity: {x: 0, y: -1, z: 0} -}); - -function cleanup() { - - // Uncomment the below line to delete sprayCan on script reload- for faster iteration during development - // Entities.deleteEntity(sprayCan); -} - -Script.scriptEnding.connect(cleanup); - From d993d397184a24d3d7b742fcadee6821cc96d10c Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 30 Sep 2015 16:28:33 -0700 Subject: [PATCH 346/418] Bug fix for deriveBodyFromHMDSensor calculations The calculation that determined where the body position relative to the HMD was incorrect, one of the components was in the wrong coordinate frame. Now use the skeleton's bind pose to compute the proper avatar offsets for the eyes, neck and hips. Use these offsets to calculate where the hips should be given a specific hmd position and orientation. Also, added a bug fix for Rig, which would cause a -1 index deference when an avatar was missing certain named joints, such as, "LeftEye", "Neck" and "Head". --- interface/src/avatar/MyAvatar.cpp | 62 +++++++++++++++++++++++++++---- libraries/animation/src/Rig.cpp | 17 +++++++-- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8f7af63a81..a57740a691 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -271,6 +271,25 @@ glm::mat4 MyAvatar::getSensorToWorldMatrix() const { return _sensorToWorldMatrix; } +// returns true if pos is OUTSIDE of the vertical capsule +// where the middle cylinder length is defined by capsuleLen and the radius by capsuleRad. +static bool capsuleCheck(const glm::vec3& pos, float capsuleLen, float capsuleRad) { + const float halfCapsuleLen = capsuleLen / 2.0f; + if (fabs(pos.y) <= halfCapsuleLen) { + // cylinder check for middle capsule + glm::vec2 horizPos(pos.x, pos.z); + return glm::length(horizPos) > capsuleRad; + } else if (pos.y > halfCapsuleLen) { + glm::vec3 center(0.0f, halfCapsuleLen, 0.0f); + return glm::length(center - pos) > capsuleRad; + } else if (pos.y < halfCapsuleLen) { + glm::vec3 center(0.0f, -halfCapsuleLen, 0.0f); + return glm::length(center - pos) > capsuleRad; + } else { + return false; + } +} + // Pass a recent sample of the HMD to the avatar. // This can also update the avatar's position to follow the HMD // as it moves through the world. @@ -289,11 +308,14 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { _hmdSensorOrientation = glm::quat_cast(hmdSensorMatrix); const float STRAIGHTING_LEAN_DURATION = 0.5f; // seconds - const float STRAIGHTING_LEAN_THRESHOLD = 0.2f; // meters + + // define a vertical capsule + const float STRAIGHTING_LEAN_CAPSULE_RADIUS = 0.2f; // meters + const float STRAIGHTING_LEAN_CAPSULE_LENGTH = 0.05f; // length of the cylinder part of the capsule in meters. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); glm::vec3 diff = extractTranslation(newBodySensorMatrix) - extractTranslation(_bodySensorMatrix); - if (!_straightingLean && glm::length(diff) > STRAIGHTING_LEAN_THRESHOLD) { + if (!_straightingLean && capsuleCheck(diff, STRAIGHTING_LEAN_CAPSULE_LENGTH, STRAIGHTING_LEAN_CAPSULE_RADIUS)) { // begin homing toward derived body position. _straightingLean = true; @@ -1854,13 +1876,39 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { const glm::quat hmdOrientation = getHMDSensorOrientation(); const glm::quat hmdOrientationYawOnly = cancelOutRollAndPitch(hmdOrientation); - // In sensor space, figure out where the avatar body should be, - // by applying offsets from the avatar's neck & head joints. - vec3 localEyes = _skeletonModel.getDefaultEyeModelPosition(); - vec3 localNeck(0.0f, 0.48f, 0.0f); // start with some kind of guess if the skeletonModel is not loaded yet. - _skeletonModel.getLocalNeckPosition(localNeck); + const glm::vec3 DEFAULT_RIGHT_EYE_POS(-0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_LEFT_EYE_POS(0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_NECK_POS(0.0f, 1.5f, 0.0f); + const glm::vec3 DEFAULT_HIPS_POS(0.0f, 1.0f, 0.0f); + + vec3 localEyes, localNeck; + if (!_debugDrawSkeleton) { + const glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + localEyes = rotY180 * (((DEFAULT_RIGHT_EYE_POS + DEFAULT_LEFT_EYE_POS) / 2.0f) - DEFAULT_HIPS_POS); + localNeck = rotY180 * (DEFAULT_NECK_POS - DEFAULT_HIPS_POS); + } else { + // TODO: At the moment MyAvatar does not have access to the rig, which has the skeleton, which has the bind poses. + // for now use the _debugDrawSkeleton, which is initialized with the same FBX model as the rig. + + // TODO: cache these indices. + int rightEyeIndex = _debugDrawSkeleton->nameToJointIndex("RightEye"); + int leftEyeIndex = _debugDrawSkeleton->nameToJointIndex("LeftEye"); + int neckIndex = _debugDrawSkeleton->nameToJointIndex("Neck"); + int hipsIndex = _debugDrawSkeleton->nameToJointIndex("Hips"); + + glm::vec3 absRightEyePos = rightEyeIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(rightEyeIndex).trans : DEFAULT_RIGHT_EYE_POS; + glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(leftEyeIndex).trans : DEFAULT_LEFT_EYE_POS; + glm::vec3 absNeckPos = neckIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(neckIndex).trans : DEFAULT_NECK_POS; + glm::vec3 absHipsPos = neckIndex != -1 ? _debugDrawSkeleton->getAbsoluteBindPose(hipsIndex).trans : DEFAULT_HIPS_POS; + + const glm::quat rotY180 = glm::angleAxis((float)PI, glm::vec3(0.0f, 1.0f, 0.0f)); + localEyes = rotY180 * (((absRightEyePos + absLeftEyePos) / 2.0f) - absHipsPos); + localNeck = rotY180 * (absNeckPos - absHipsPos); + } // apply simplistic head/neck model + // figure out where the avatar body should be by applying offsets from the avatar's neck & head joints. + // eyeToNeck offset is relative full HMD orientation. // while neckToRoot offset is only relative to HMDs yaw. glm::vec3 eyeToNeck = hmdOrientation * (localNeck - localEyes); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0022749d51..1e512ee767 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1026,12 +1026,21 @@ static void computeHeadNeckAnimVars(AnimSkeleton::ConstPointer skeleton, const A const glm::quat hmdOrientation = hmdPose.rot * rotY180; // rotY180 will make z forward not -z // TODO: cache jointIndices + int rightEyeIndex = skeleton->nameToJointIndex("RightEye"); + int leftEyeIndex = skeleton->nameToJointIndex("LeftEye"); + int headIndex = skeleton->nameToJointIndex("Head"); + int neckIndex = skeleton->nameToJointIndex("Neck"); + + const glm::vec3 DEFAULT_RIGHT_EYE_POS(-0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_LEFT_EYE_POS(0.3f, 1.6f, 0.0f); + const glm::vec3 DEFAULT_HEAD_POS(0.0f, 1.55f, 0.0f); + const glm::vec3 DEFAULT_NECK_POS(0.0f, 1.5f, 0.0f); // Use absolute bindPose positions just in case the relBindPose have rotations we don't expect. - glm::vec3 absRightEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("RightEye")).trans; - glm::vec3 absLeftEyePos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("LeftEye")).trans; - glm::vec3 absHeadPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Head")).trans; - glm::vec3 absNeckPos = skeleton->getAbsoluteBindPose(skeleton->nameToJointIndex("Neck")).trans; + glm::vec3 absRightEyePos = rightEyeIndex != -1 ? skeleton->getAbsoluteBindPose(rightEyeIndex).trans : DEFAULT_RIGHT_EYE_POS; + glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? skeleton->getAbsoluteBindPose(leftEyeIndex).trans : DEFAULT_LEFT_EYE_POS; + glm::vec3 absHeadPos = headIndex != -1 ? skeleton->getAbsoluteBindPose(headIndex).trans : DEFAULT_HEAD_POS; + glm::vec3 absNeckPos = neckIndex != -1 ? skeleton->getAbsoluteBindPose(neckIndex).trans : DEFAULT_NECK_POS; glm::vec3 absCenterEyePos = (absRightEyePos + absLeftEyePos) / 2.0f; glm::vec3 eyeOffset = absCenterEyePos - absHeadPos; From 3592b78b2b1ea4e2c646a8f6385a8bafe4cfc022 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 16:35:43 -0700 Subject: [PATCH 347/418] less points per line --- examples/closePaint.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index dc3e567823..fdd7d7cac6 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -26,7 +26,7 @@ var TRIGGER_ON_VALUE = 0.3; var MAX_DISTANCE = 10; var STROKE_WIDTH = 0.02 -var MAX_POINTS_PER_LINE = 60; +var MAX_POINTS_PER_LINE = 40; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -221,6 +221,10 @@ function MyController(hand, triggerAction) { var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); +Controller.actionEvent.connect(function(action, state) { + print("ACTION " + action) +}); + function update() { rightController.update(); leftController.update(); From 2899962d43f61990b36e78ed977a8e5443b9e579 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 17:14:17 -0700 Subject: [PATCH 348/418] can now cycle colors with 4 and 2 buttons on hydra --- examples/closePaint.js | 100 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index fdd7d7cac6..fba2aa0e80 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -28,6 +28,14 @@ var MAX_DISTANCE = 10; var STROKE_WIDTH = 0.02 var MAX_POINTS_PER_LINE = 40; +var RIGHT_4_ACTION = 18; +var RIGHT_2_ACTION = 16; + +var LEFT_4_ACTION = 17; +var LEFT_2_ACTION = 16; + +var HUE_INCREMENT = 0.01; + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -52,9 +60,9 @@ function MyController(hand, triggerAction) { this.strokeColor = { - red: 200, - green: 20, - blue: 40 + h: 0.8, + s: 0.9, + l: 0.4 }; this.laserPointer = Overlays.addOverlay("circle3d", { @@ -62,7 +70,7 @@ function MyController(hand, triggerAction) { x: STROKE_WIDTH / 2, y: STROKE_WIDTH / 2 }, - color: this.strokeColor, + color: hslToRgb(this.strokeColor), solid: true, position: center }) @@ -80,7 +88,6 @@ function MyController(hand, triggerAction) { }; this.paint = function(position, normal) { - // print("POSITION " + position.z) if (this.painting === false) { if (this.oldPosition) { this.newStroke(this.oldPosition); @@ -101,13 +108,17 @@ function MyController(hand, triggerAction) { //need a minimum distance to avoid binormal NANs return; } - if(this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { //Prevents drawing lines accross models this.painting = false; return; } - if(this.strokePoints.length === 0) { - localPoint = {x: 0, y: 0, z: 0}; + if (this.strokePoints.length === 0) { + localPoint = { + x: 0, + y: 0, + z: 0 + }; } this.strokePoints.push(localPoint); @@ -122,8 +133,7 @@ function MyController(hand, triggerAction) { this.painting = false; return; } - this.oldPosition = position - + this.oldPosition = position } this.newStroke = function(position) { @@ -131,7 +141,7 @@ function MyController(hand, triggerAction) { this.currentStroke = Entities.addEntity({ position: position, type: "PolyLine", - color: this.strokeColor, + color: hslToRgb(this.strokeColor), dimensions: { x: 50, y: 50, @@ -216,13 +226,39 @@ function MyController(hand, triggerAction) { Entities.deleteEntity(stroke); }); } + + this.cycleColorDown = function() { + this.strokeColor.h -= HUE_INCREMENT; + if (this.strokeColor.h < 0) { + this.strokeColor = 1; + } + } + + this.cycleColorUp = function() { + this.strokeColor.h += HUE_INCREMENT; + if (this.strokeColor.h > 1) { + this.strokeColor.h = 0; + } + } } var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); Controller.actionEvent.connect(function(action, state) { - print("ACTION " + action) + if (state === 0) { + return; + } + if (action === RIGHT_4_ACTION) { + rightController.cycleColorUp(); + } else if (action === RIGHT_2_ACTION) { + rightController.cycleColorDown(); + } + if (action === LEFT_4_ACTION) { + leftController.cycleColorUp(); + } else if (action === LEFT_2_ACTION) { + leftController.cycleColorDown(); + } }); function update() { @@ -259,4 +295,44 @@ function orientationOf(vector) { yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); return Quat.multiply(yaw, pitch); +} + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +function hslToRgb(hsl) { + var r, g, b; + + if (hsl.s == 0) { + r = g = b = hsl.l; // achromatic + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; + var p = 2 * hsl.l - q; + r = hue2rgb(p, q, hsl.h + 1 / 3); + g = hue2rgb(p, q, hsl.h); + b = hue2rgb(p, q, hsl.h - 1 / 3); + } + + return { + red: Math.round(r * 255), + green: Math.round(g * 255), + blue: Math.round(b * 255) + }; } \ No newline at end of file From be9b244779a6b4e34156a22d43004f2fde06d18d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:21:52 -0700 Subject: [PATCH 349/418] Fix the skybox color issue with background rendering when no texture is there --- libraries/model/src/model/Skybox.cpp | 113 +++++++++++++++------------ libraries/model/src/model/Skybox.slf | 10 ++- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 944d16a6dd..4d49492c39 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -45,11 +45,18 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { + const int VERTICES_SLOT = 0; + const int COLOR_SLOT = 1; + + // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; - - if (skybox.getCubemap()) { - if (!theBuffer) { + static gpu::BufferPointer theConstants; + static gpu::PipelinePointer thePipeline; + static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + static std::once_flag once; + std::call_once(once, [&] { + { const float CLIP = 1.0f; const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } }; theBuffer = std::make_shared(sizeof(vertices), (const gpu::Byte*) vertices); @@ -57,63 +64,65 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); } - glm::mat4 projMat; - viewFrustum.evalProjectionMatrix(projMat); + { + auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); + auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); + auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - Transform viewTransform; - viewFrustum.evalViewTransform(viewTransform); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewTransform); - batch.setModelTransform(Transform()); // only for Mac - batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); - batch.setInputFormat(theFormat); + gpu::Shader::BindingSet bindings; + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { - static gpu::BufferPointer theConstants; - static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader - if (!thePipeline) { - auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); - auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); - auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - - gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); - if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - - } - - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - - auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - - thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - auto color = glm::vec4(1.0f); - theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color); - } else { - theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor()); + SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); + if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { + SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); } - batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skybox.getCubemap()); - batch.draw(gpu::TRIANGLE_STRIP, 4); + auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + + thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + + auto color = glm::vec4(1.0f); + theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } + }); - } else { - // skybox has no cubemap, just clear the color buffer - auto color = skybox.getColor(); - batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.0f, 0, true); + // Render + glm::mat4 projMat; + viewFrustum.evalProjectionMatrix(projMat); + + Transform viewTransform; + viewFrustum.evalViewTransform(viewTransform); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewTransform); + batch.setModelTransform(Transform()); // only for Mac + batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); + batch.setInputFormat(theFormat); + + gpu::TexturePointer skymap; + auto color = glm::vec4(skybox.getColor(), 0.0f); + if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { + skymap = skybox.getCubemap(); + + if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { + color = glm::vec4(1.0f); + } else { + color.w = 1.0f; + } } + // Update the constant color. + theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); + + batch.setPipeline(thePipeline); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); + batch.setResourceTexture(0, skymap); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + + batch.setResourceTexture(0, nullptr); + } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 382801f52d..66abee8948 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -40,8 +40,14 @@ void main(void) { #else vec3 coord = normalize(_normal); - vec3 texel = texture(cubeMap, coord).rgb; - vec3 color = texel * _skybox._color.rgb; + + // Skybox color or blend with skymap + vec3 color = _skybox._color.rgb; + if (_skybox._color.a > 0.0) { + vec3 texel = texture(cubeMap, coord).rgb; + color *= texel; + } + vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction _fragColor = vec4(pixel, 0.0); From c01077a0d7c425ceadac7f9f3f1335c5107b44ca Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 30 Sep 2015 17:30:34 -0700 Subject: [PATCH 350/418] real fix --- assignment-client/src/Agent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 4438782ae5..d9109703cb 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -233,8 +233,8 @@ void Agent::setIsAvatar(bool isAvatar) { } if (_avatarBillboardTimer) { - _avatarIdentityTimer->stop(); - delete _avatarIdentityTimer; + _avatarBillboardTimer->stop(); + delete _avatarBillboardTimer; _avatarBillboardTimer = nullptr; } } From d3d47752327dd0a90fee77e30993d5c16bcb0193 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:54:20 -0700 Subject: [PATCH 351/418] THe dataBuffer contining the properties of the skybox is now per instace and not static and shared so it's static from frames to frames --- libraries/model/src/model/Skybox.cpp | 55 ++++++++++--------- libraries/model/src/model/Skybox.h | 18 ++++-- .../src/procedural/ProceduralSkybox.cpp | 1 + 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4d49492c39..7c22d7a062 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -21,6 +21,8 @@ using namespace model; Skybox::Skybox() { + Data data; + _dataBuffer = gpu::BufferView(std::make_shared(sizeof(Data), (const gpu::Byte*) &data)); /* // PLease create a default engineer skybox _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); @@ -36,7 +38,7 @@ Skybox::Skybox() { } void Skybox::setColor(const Color& color) { - _color = color; + _dataBuffer.edit()._color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { @@ -44,16 +46,33 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { } -void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { - const int VERTICES_SLOT = 0; - const int COLOR_SLOT = 1; +void Skybox::updateDataBuffer() const { + auto blend = 0.0f; + if (getCubemap() && getCubemap()->isDefined()) { + blend = 1.0f; + } + if (blend != _dataBuffer.get()._blend) { + _dataBuffer.edit()._blend = blend; + } +} + + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { + updateDataBuffer(); + Skybox::render(batch, frustum, (*this)); +} + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; static gpu::BufferPointer theConstants; static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + const int SKYBOX_SKYMAP_SLOT = 0; + const int SKYBOX_CONSTANTS_SLOT = 0; static std::once_flag once; std::call_once(once, [&] { { @@ -70,23 +89,16 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), SKYBOX_SKYMAP_SLOT)); + bindings.insert(gpu::Shader::Binding(std::string("skyboxBuffer"), SKYBOX_CONSTANTS_SLOT)); if (!gpu::Shader::makeProgram(*skyShader, bindings)) { } - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - auto skyState = std::make_shared(); skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } }); @@ -103,26 +115,17 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setInputFormat(theFormat); gpu::TexturePointer skymap; - auto color = glm::vec4(skybox.getColor(), 0.0f); if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { skymap = skybox.getCubemap(); - - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - color = glm::vec4(1.0f); - } else { - color.w = 1.0f; - } } - // Update the constant color. - theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skymap); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._dataBuffer); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index e9f95afa16..14ba9fa005 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -30,20 +30,28 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color& getColor() const { return _color; } + const Color getColor() const { return _dataBuffer.get()._color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } - virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const { - render(batch, frustum, (*this)); - } + virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; + static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); protected: gpu::TexturePointer _cubemap; - Color _color{1.0f, 1.0f, 1.0f}; + + class Data { + public: + glm::vec3 _color{ 1.0f, 1.0f, 1.0f }; + float _blend = 1.0f; + }; + + mutable gpu::BufferView _dataBuffer; + + void updateDataBuffer() const; }; typedef std::shared_ptr< Skybox > SkyboxPointer; diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index f69e0575de..1c7e7e457c 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -43,6 +43,7 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) con void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { if (!(skybox._procedural)) { + skybox.updateDataBuffer(); Skybox::render(batch, viewFrustum, skybox); } From 69c40754390f7e70dcfcd16f79bf14f278e5286f Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:08:01 -0700 Subject: [PATCH 352/418] Fix the behavior when skybox color is black and skymap is available --- libraries/model/src/model/Skybox.cpp | 4 ++++ libraries/model/src/model/Skybox.slf | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 7c22d7a062..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -50,6 +50,10 @@ void Skybox::updateDataBuffer() const { auto blend = 0.0f; if (getCubemap() && getCubemap()->isDefined()) { blend = 1.0f; + // If pitch black neutralize the color + if (glm::all(glm::equal(getColor(), glm::vec3(0.0f)))) { + blend = 2.0f; + } } if (blend != _dataBuffer.get()._blend) { diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 66abee8948..a6283055d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -45,7 +45,9 @@ void main(void) { vec3 color = _skybox._color.rgb; if (_skybox._color.a > 0.0) { vec3 texel = texture(cubeMap, coord).rgb; - color *= texel; + if (_skybox._color.a < 2.0) { + color *= texel; + } } vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction From 0398f9429e9d7d21f181167664b52eb0799aecd7 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:39:13 -0700 Subject: [PATCH 353/418] fix the coo/texel blender mode for the case when color is black and the stereo issue --- libraries/model/src/model/Skybox.cpp | 2 +- libraries/model/src/model/Skybox.slf | 2 ++ libraries/render-utils/src/RenderDeferredTask.cpp | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 21b40a54c8..e516fae583 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index a6283055d3..6246bbd9d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -47,6 +47,8 @@ void main(void) { vec3 texel = texture(cubeMap, coord).rgb; if (_skybox._color.a < 2.0) { color *= texel; + } else { + color = texel; } } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e16544f5cd..504070963d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -335,9 +335,10 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.clearStencilFramebuffer(0, true); + Transform modelMat; batch.setModelTransform(modelMat); From 5da5bd47af36c83eb5d19bdb7f494c93b509abb9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 30 Sep 2015 21:45:22 -0400 Subject: [PATCH 354/418] add a missing rename for socket Q_ASSERT_X --- libraries/networking/src/udt/Connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 1bda840a6c..e8b22f6ab8 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -32,7 +32,7 @@ Connection::Connection(Socket* parentSocket, HifiSockAddr destination, std::uniq _destination(destination), _congestionControl(move(congestionControl)) { - Q_ASSERT_X(socket, "Connection::Connection", "Must be called with a valid Socket*"); + Q_ASSERT_X(parentSocket, "Connection::Connection", "Must be called with a valid Socket*"); Q_ASSERT_X(_congestionControl, "Connection::Connection", "Must be called with a valid CongestionControl object"); _congestionControl->init(); From 4e29d8382dc4a026b60fccd81c050776c34d17bc Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 03:24:10 -0700 Subject: [PATCH 355/418] SSE2 optimization of new resampler. 3.5x faster for all modes. Dither is always enabled. --- libraries/audio/src/AudioSRC.cpp | 400 ++++++++++++++++++++++++++----- 1 file changed, 343 insertions(+), 57 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index 736b098def..e33d399213 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -558,30 +558,8 @@ static const float Q32_TO_FLOAT = 1.0f / (1ULL << 32); // blocking size in frames, chosen so block processing fits in L1 cache static const int SRC_BLOCK = 1024; -//#define SRC_DITHER -#define RAND16(r) (((r) = (r) * 69069u + 1u) >> 16) - -// these are performance sensitive -#define lo32(a) (((uint32_t* )&(a))[0]) -#define hi32(a) (((int32_t* )&(a))[1]) - -//#define lo32(a) ((uint32_t)(a)) -//#define hi32(a) ((int32_t)((a) >> 32)) - -//static inline uint32_t lo32(int64_t a) { -// union { -// int64_t val; -// struct { uint32_t lo; int32_t hi; } reg; -// } b = { a }; -// return b.reg.lo; -//} -//static inline int32_t hi32(int64_t a) { -// union { -// int64_t val; -// struct { uint32_t lo; int32_t hi; } reg; -// } b = { a }; -// return b.reg.hi; -//} +#define lo32(a) ((uint32_t)(a)) +#define hi32(a) ((int32_t)((a) >> 32)) // // Portable aligned malloc/free @@ -671,6 +649,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { numTaps = (numCoefs + upFactor - 1) / upFactor; gain *= (float)oldCoefs / numCoefs; } + numTaps = (numTaps + 3) & ~3; // SIMD4 // interpolate the coefficients of the prototype filter float* tempFilter = new float[numTaps * numPhases]; @@ -679,7 +658,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain); // create the polyphase filter - _polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 32); + _polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 16); // SIMD4 // rearrange into polyphase form, ordered by use for (int i = 0; i < numPhases; i++) { @@ -720,6 +699,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { numTaps = (numCoefs + upFactor - 1) / upFactor; gain *= (float)oldCoefs / numCoefs; } + numTaps = (numTaps + 3) & ~3; // SIMD4 // interpolate the coefficients of the prototype filter float* tempFilter = new float[numTaps * numPhases]; @@ -728,7 +708,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain); // create the polyphase filter, with extra phase at the end to simplify coef interpolation - _polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 32); + _polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 16); // SIMD4 // rearrange into polyphase form, ordered by fractional delay for (int phase = 0; phase < numPhases; phase++) { @@ -754,6 +734,284 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { return numTaps; } +// +// on x86 architecture, assume that SSE2 is present +// +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__) + +#include + +int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) { + int outputFrames = 0; + + assert((_numTaps & 0x3) == 0); // SIMD4 + + if (_step == 0) { // rational + + int32_t i = hi32(_offset); + + while (i < inputFrames) { + + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; + + __m128 acc0 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j]; + __m128 coef0 = _mm_loadu_ps(&c0[j]); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } + } + _offset = (int64_t)(i - inputFrames) << 32; + + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + __m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT); + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + __m128 acc0 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j] + frac * (c1[j] - c0[j]); + __m128 coef0 = _mm_loadu_ps(&c0[j]); + __m128 coef1 = _mm_loadu_ps(&c1[j]); + coef1 = _mm_sub_ps(coef1, coef0); + coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; + } + + return outputFrames; +} + +int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) { + int outputFrames = 0; + + assert((_numTaps & 0x3) == 0); // SIMD4 + + if (_step == 0) { // rational + + int32_t i = hi32(_offset); + + while (i < inputFrames) { + + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; + + __m128 acc0 = _mm_setzero_ps(); + __m128 acc1 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j]; + __m128 coef0 = _mm_loadu_ps(&c0[j]); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc1 = _mm_add_ps(acc1, _mm_movehl_ps(acc1, acc1)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + acc1 = _mm_add_ss(acc1, _mm_shuffle_ps(acc1, acc1, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + _mm_store_ss(&output1[outputFrames], acc1); + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } + } + _offset = (int64_t)(i - inputFrames) << 32; + + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + __m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT); + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + __m128 acc0 = _mm_setzero_ps(); + __m128 acc1 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j] + frac * (c1[j] - c0[j]); + __m128 coef0 = _mm_loadu_ps(&c0[j]); + __m128 coef1 = _mm_loadu_ps(&c1[j]); + coef1 = _mm_sub_ps(coef1, coef0); + coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc1 = _mm_add_ps(acc1, _mm_movehl_ps(acc1, acc1)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + acc1 = _mm_add_ss(acc1, _mm_shuffle_ps(acc1, acc1, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + _mm_store_ss(&output1[outputFrames], acc1); + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; + } + + return outputFrames; +} + +// convert int16_t to float, deinterleave stereo +void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { + __m128 scale = _mm_set1_ps(1/32768.0f); + + numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute + assert(numFrames <= SRC_BLOCK); + + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i += 4) { + + __m128i a0 = _mm_loadl_epi64((__m128i*)&input[i]); + + // sign-extend + a0 = _mm_srai_epi32(_mm_unpacklo_epi16(a0, a0), 16); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + + _mm_storeu_ps(&outputs[0][i], f0); + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i += 4) { + + __m128i a0 = _mm_loadu_si128((__m128i*)&input[2*i]); + __m128i a1 = a0; + + // deinterleave and sign-extend + a0 = _mm_madd_epi16(a0, _mm_set1_epi32(0x00000001)); + a1 = _mm_madd_epi16(a1, _mm_set1_epi32(0x00010000)); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + __m128 f1 = _mm_mul_ps(_mm_cvtepi32_ps(a1), scale); + + _mm_storeu_ps(&outputs[0][i], f0); + _mm_storeu_ps(&outputs[1][i], f1); + } + } +} + +// fast TPDF dither in [-1.0f, 1.0f] +static inline __m128 dither4() { + static __m128i rz = _mm_set_epi16(0, -12285, 8251, 22985, -4297, 14758, -19785, -26093); + + // update the parallel LCGs + rz = _mm_mullo_epi16(rz, _mm_set1_epi16(25173)); + rz = _mm_add_epi16(rz, _mm_set1_epi16(13849)); + + // promote to 32-bit + __m128i r0 = _mm_unpacklo_epi16(rz, _mm_setzero_si128()); + __m128i r1 = _mm_unpackhi_epi16(rz, _mm_setzero_si128()); + + // return (r0 - r1) * (1/65536.0f); + __m128 d0 = _mm_cvtepi32_ps(_mm_sub_epi32(r0, r1)); + return _mm_mul_ps(d0, _mm_set1_ps(1/65536.0f)); +} + +// convert float to int16_t, interleave stereo +void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { + __m128 scale = _mm_set1_ps(32768.0f); + + numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute + assert(numFrames <= SRC_BLOCK); + + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i += 4) { + + __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); + + f0 = _mm_add_ps(f0, dither4()); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + a0 = _mm_packs_epi32(a0, a0); + + _mm_storel_epi64((__m128i*)&output[i], a0); + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i += 4) { + + __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); + __m128 f1 = _mm_mul_ps(_mm_loadu_ps(&inputs[1][i]), scale); + + __m128 d0 = dither4(); + f0 = _mm_add_ps(f0, d0); + f1 = _mm_add_ps(f1, d0); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + __m128i a1 = _mm_cvtps_epi32(f1); + a0 = _mm_packs_epi32(a0, a0); + a1 = _mm_packs_epi32(a1, a1); + + // interleave + a0 = _mm_unpacklo_epi16(a0, a1); + + _mm_storeu_si128((__m128i*)&output[2*i], a0); + } + } +} + +#else + int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) { int outputFrames = 0; @@ -886,45 +1144,73 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* return outputFrames; } -// convert int16_t to float -// deinterleave stereo samples +// convert int16_t to float, deinterleave stereo void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { - for (int i = 0; i < numFrames; i++) { - for (int j = 0; j < _numChannels; j++) { + const float scale = 1/32768.0f; - float f = (float)input[_numChannels*i + j]; - outputs[j][i] = f * (1.0f/32768.0f); + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i++) { + outputs[0][i] = (float)input[i] * scale; + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i++) { + outputs[0][i] = (float)input[2*i + 0] * scale; + outputs[1][i] = (float)input[2*i + 1] * scale; } } } -// convert float to int16_t -// interleave stereo samples +// fast TPDF dither in [-1.0f, 1.0f] +static inline float dither() { + static uint32_t rz = 0; + rz = rz * 69069 + 1; + int32_t r0 = rz & 0xffff; + int32_t r1 = rz >> 16; + return (r0 - r1) * (1/65536.0f); +} + +// convert float to int16_t, interleave stereo void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { - for (int i = 0; i < numFrames; i++) { - for (int j = 0; j < _numChannels; j++) { + const float scale = 32768.0f; - float f = inputs[j][i] * 32768.0f; + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i++) { -#ifdef SRC_DITHER - // TPDF dither in [-1.0f, 1.0f] - static uint32_t rz = 1; - int r0 = RAND16(rz); - int r1 = RAND16(rz); - f += (r0 - r1) * (1.0f/65536.0f); + float f = inputs[0][i] * scale; - // round + f += dither(); + + // round and saturate f += (f < 0.0f ? -0.5f : +0.5f); -#endif - // saturate - f = std::min(f, 32767.0f); - f = std::max(f, -32768.0f); + f = std::max(std::min(f, 32767.0f), -32768.0f); - output[_numChannels * i + j] = (int16_t)f; + output[i] = (int16_t)f; + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i++) { + + float f0 = inputs[0][i] * scale; + float f1 = inputs[1][i] * scale; + + float d = dither(); + f0 += d; + f1 += d; + + // round and saturate + f0 += (f0 < 0.0f ? -0.5f : +0.5f); + f1 += (f1 < 0.0f ? -0.5f : +0.5f); + f0 = std::max(std::min(f0, 32767.0f), -32768.0f); + f1 = std::max(std::min(f1, 32767.0f), -32768.0f); + + // interleave + output[2*i + 0] = (int16_t)f0; + output[2*i + 1] = (int16_t)f1; } } } +#endif + int AudioSRC::processFloat(float** inputs, float** outputs, int inputFrames) { int outputFrames = 0; @@ -1019,10 +1305,10 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) { _history[1] = new float[2 * _numHistory]; // format conversion buffers - _inputs[0] = new float[SRC_BLOCK]; - _inputs[1] = new float[SRC_BLOCK]; - _outputs[0] = new float[SRC_BLOCK]; - _outputs[1] = new float[SRC_BLOCK]; + _inputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); // SIMD4 + _inputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); + _outputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); + _outputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); // input blocking size, such that input and output are both guaranteed not to exceed SRC_BLOCK frames _inputBlock = std::min(SRC_BLOCK, getMaxInput(SRC_BLOCK)); @@ -1041,10 +1327,10 @@ AudioSRC::~AudioSRC() { delete[] _history[0]; delete[] _history[1]; - delete[] _inputs[0]; - delete[] _inputs[1]; - delete[] _outputs[0]; - delete[] _outputs[1]; + aligned_free(_inputs[0]); + aligned_free(_inputs[1]); + aligned_free(_outputs[0]); + aligned_free(_outputs[1]); } // From 191a4740a392905e148238aa60198749ea2b11fb Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 09:50:58 -0700 Subject: [PATCH 356/418] laser color matches paint color --- examples/acScripts/rain.js | 6 ++++-- examples/closePaint.js | 17 +++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/examples/acScripts/rain.js b/examples/acScripts/rain.js index 3f38b8d36a..fc02b7163f 100644 --- a/examples/acScripts/rain.js +++ b/examples/acScripts/rain.js @@ -18,7 +18,7 @@ var RainSquall = function (properties) { dropFallSpeed = 1, // m/s dropLifetime = 60, // Seconds dropSpinMax = 0, // Maximum angular velocity per axis; deg/s - debug = false, // Display origin circle; don't use running on Stack Manager + debug = true, // Display origin circle; don't use running on Stack Manager // Other squallCircle, SQUALL_CIRCLE_COLOR = { red: 255, green: 0, blue: 0 }, @@ -151,8 +151,10 @@ var RainSquall = function (properties) { }; }; +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +center.y += 10; var rainSquall1 = new RainSquall({ - origin: { x: 1195, y: 1223, z: 1020 }, + origin:center, radius: 25, dropsPerMinute: 120, dropSize: { x: 0.1, y: 0.1, z: 0.1 }, diff --git a/examples/closePaint.js b/examples/closePaint.js index fba2aa0e80..c17402857b 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -34,7 +34,7 @@ var RIGHT_2_ACTION = 16; var LEFT_4_ACTION = 17; var LEFT_2_ACTION = 16; -var HUE_INCREMENT = 0.01; +var HUE_INCREMENT = 0.02; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -61,16 +61,17 @@ function MyController(hand, triggerAction) { this.strokeColor = { h: 0.8, - s: 0.9, + s: 0.8, l: 0.4 }; + this.laserPointer = Overlays.addOverlay("circle3d", { size: { x: STROKE_WIDTH / 2, y: STROKE_WIDTH / 2 }, - color: hslToRgb(this.strokeColor), + color: hslToRgb(this.strokeColor ), solid: true, position: center }) @@ -78,7 +79,6 @@ function MyController(hand, triggerAction) { this.prevTriggerValue = 0; var _this = this; - this.update = function() { this.updateControllerState() this.search(); @@ -232,6 +232,9 @@ function MyController(hand, triggerAction) { if (this.strokeColor.h < 0) { this.strokeColor = 1; } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } this.cycleColorUp = function() { @@ -239,6 +242,9 @@ function MyController(hand, triggerAction) { if (this.strokeColor.h > 1) { this.strokeColor.h = 0; } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } } @@ -308,9 +314,8 @@ function orientationOf(vector) { * @param Number l The lightness * @return Array The RGB representation */ -function hslToRgb(hsl) { +function hslToRgb(hsl, hueOffset) { var r, g, b; - if (hsl.s == 0) { r = g = b = hsl.l; // achromatic } else { From d4f954a0e2ee1c5c27bcd161bb6fd1a8be880923 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 10:25:30 -0700 Subject: [PATCH 357/418] allow more than one near-grab on an object --- examples/controllers/handControllerGrab.js | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index e756866b1c..4dd9dca7a2 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -242,8 +242,7 @@ function MyController(hand, triggerAction) { var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0 && - !entityIsGrabbedByOther(intersection.entityID)) { + intersection.properties.locked === 0) { // the ray is intersecting something we can move. var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); @@ -258,6 +257,10 @@ function MyController(hand, triggerAction) { this.state = STATE_NEAR_GRABBING; } else { + if (entityIsGrabbedByOther(intersection.entityID)) { + // don't allow two people to distance grab the same object + return; + } // the hand is far from the intersected object. go into distance-holding mode this.state = STATE_DISTANCE_HOLDING; this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); @@ -441,16 +444,13 @@ function MyController(hand, triggerAction) { var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); this.actionID = NULL_ACTION_ID; - if (!entityIsGrabbedByOther(this.grabbedEntity)) { - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand === RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation, - tag: getTag(), - lifetime: ACTION_LIFETIME - }); - } + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + hand: this.hand === RIGHT_HAND ? "right" : "left", + timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, + relativePosition: offsetPosition, + relativeRotation: offsetRotation, + lifetime: ACTION_LIFETIME + }); if (this.actionID === NULL_ACTION_ID) { this.actionID = null; } else { From 2700529b33921a9c2fc1f526256faca759a42c47 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 10:41:43 -0700 Subject: [PATCH 358/418] lower action lifetime --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 4dd9dca7a2..5705bd4498 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -66,7 +66,7 @@ var MSEC_PER_SEC = 1000.0; // these control how long an abandoned pointer line will hang around var startTime = Date.now(); var LIFETIME = 10; -var ACTION_LIFETIME = 120; // 2 minutes +var ACTION_LIFETIME = 10; // seconds // states for the state machine var STATE_OFF = 0; From 335d87134b73d80adaf14ad40984dbfab7a0f0c0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 1 Oct 2015 10:58:31 -0700 Subject: [PATCH 359/418] Squash compiler warning in AnimVariant. --- libraries/animation/src/AnimVariant.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index 700a8b4121..cb886cd369 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -184,6 +184,8 @@ public: case AnimVariant::Type::String: qCDebug(animation) << " " << pair.first << "=" << pair.second.getString(); break; + default: + assert("AnimVariant::Type" == "valid"); } } } From ef5ad9eeb3eea43592872ec6a139898f00e32749 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 11:02:22 -0700 Subject: [PATCH 360/418] Laser stays visible when further away from surfaces --- examples/closePaint.js | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index c17402857b..fa692e0bbc 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -21,11 +21,10 @@ var MAX_POINT_DISTANCE = 0.5; var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; -var TRIGGER_ON_VALUE = 0.3; +var TRIGGER_ON_VALUE = 0.1; var MAX_DISTANCE = 10; -var STROKE_WIDTH = 0.02 var MAX_POINTS_PER_LINE = 40; var RIGHT_4_ACTION = 18; @@ -36,6 +35,9 @@ var LEFT_2_ACTION = 16; var HUE_INCREMENT = 0.02; +var MIN_STROKE_WIDTH = 0.005; +var MAX_STROKE_WIDTH = 0.03; + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -45,6 +47,7 @@ function MyController(hand, triggerAction) { this.hand = hand; this.strokes = []; this.painting = false; + this.currentStrokeWidth = MIN_STROKE_WIDTH; if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; @@ -67,11 +70,7 @@ function MyController(hand, triggerAction) { this.laserPointer = Overlays.addOverlay("circle3d", { - size: { - x: STROKE_WIDTH / 2, - y: STROKE_WIDTH / 2 - }, - color: hslToRgb(this.strokeColor ), + color: hslToRgb(this.strokeColor), solid: true, position: center }) @@ -123,7 +122,7 @@ function MyController(hand, triggerAction) { this.strokePoints.push(localPoint); this.strokeNormals.push(normal); - this.strokeWidths.push(STROKE_WIDTH); + this.strokeWidths.push(this.currentStrokeWidth); Entities.editEntity(this.currentStroke, { linePoints: this.strokePoints, normals: this.strokeNormals, @@ -158,14 +157,14 @@ function MyController(hand, triggerAction) { } this.updateControllerState = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - if (triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.triggerValue = Controller.getActionValue(this.triggerAction); + if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { this.squeeze(); - } else if (triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { this.release() } - this.prevTriggerValue = triggerValue; + this.prevTriggerValue = this.triggerValue; } this.squeeze = function() { @@ -193,14 +192,21 @@ function MyController(hand, triggerAction) { var distance = Vec3.distance(handPosition, this.intersection.intersection); if (distance < MAX_DISTANCE) { var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .001)); + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); if (this.tryPainting) { this.canPaint = true; } + this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); + laserSize += this.currentStrokeWidth/2; Overlays.editOverlay(this.laserPointer, { visible: true, position: displayPoint, - rotation: orientationOf(this.intersection.surfaceNormal) + rotation: orientationOf(this.intersection.surfaceNormal), + size: { + x: laserSize, + y: laserSize + } }); } else { @@ -340,4 +346,8 @@ function hslToRgb(hsl, hueOffset) { green: Math.round(g * 255), blue: Math.round(b * 255) }; +} + +function map(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); } \ No newline at end of file From d0bec38603a9de2b97852ca5e96797826aec53e8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 1 Oct 2015 11:30:50 -0700 Subject: [PATCH 361/418] Fix currentAPI.js --- examples/utilities/tools/currentAPI.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/utilities/tools/currentAPI.js b/examples/utilities/tools/currentAPI.js index 30b24910f9..cb9f152794 100644 --- a/examples/utilities/tools/currentAPI.js +++ b/examples/utilities/tools/currentAPI.js @@ -10,22 +10,21 @@ // var array = []; -var buffer = "\n\n\n\n\n======= JS API list ======="; function listKeys(string, object) { - if (string == "listKeys" || string == "array" || string == "buffer" || string == "i") { + if (string === "listKeys" || string === "array" || string === "buffer" || string === "i") { return; } - if (typeof(object) != "object") { + if (typeof(object) !== "object" || object === null) { array.push(string + " " + typeof(object)); return; } var keys = Object.keys(object); for (var i = 0; i < keys.length; ++i) { - if (string == "") { + if (string === "") { listKeys(keys[i], object[keys[i]]); - } else { + } else if (keys[i] !== "parent") { listKeys(string + "." + keys[i], object[keys[i]]); } } @@ -34,9 +33,10 @@ function listKeys(string, object) { listKeys("", this); array.sort(); +var buffer = "\n======= JS API list ======="; for (var i = 0; i < array.length; ++i) { - buffer = buffer + "\n" + array[i]; + buffer += "\n" + array[i]; } -buffer = buffer + "\n========= API END =========\n\n\n\n\n"; +buffer += "\n========= API END =========\n"; print(buffer); From a4105eb321a30581ad5673f0dfa3af6a5dedbd88 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 11:34:02 -0700 Subject: [PATCH 362/418] add color pickers --- examples/particle_explorer/main.js | 75 +++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 9ac556f961..6c9d812280 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -10,7 +10,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ +/*global window, alert, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { this.exportSettings = function() { @@ -19,15 +19,15 @@ var Settings = function() { this.importSettings = function() { importSettings(); } - - return; }; var controllers = []; +var colorControllers = []; var folders = []; var gui; var settings = new Settings(); var updateInterval; +var AUTO_UPDATE = false; var UPDATE_ALL_FREQUENCY = 1000; var keysToIgnore = [ @@ -113,6 +113,7 @@ function loadGUI() { if (shouldIgnore) { return; } + var subKeys = _.keys(settings[key]); var hasX = _.contains(subKeys, 'x'); var hasY = _.contains(subKeys, 'y'); @@ -148,7 +149,9 @@ function loadGUI() { gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + if(AUTO_UPDATE){ + setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + } } @@ -171,15 +174,43 @@ function addIndividualKeys() { } function addFolders() { + _.each(colorKeys, function(key) { + console.log('COLOR KEY IS' + key) + // createColorFolder(key); + createColorPicker(key); + }); _.each(vec3Keys, function(key) { createVec3Folder(key); }); _.each(quatKeys, function(key) { createQuatFolder(key); }); - _.each(colorKeys, function(key) { - createColorFolder(key); + +} + +function createColorPicker(key) { + console.log('CREATE COLOR PICKER') + var colorObject = settings[key]; + var colorArray = convertColorObjectToArray(colorObject); + settings[key] = colorArray; + var controller = gui.addColor(settings, key); + controller.onChange(function(value) { + console.log('COLOR VALUE' + value) + var obj = {}; + obj[key] = convertColorArrayToObject(value); + console.log('AFTER CONVERSION'); + writeVec3ToInterface(obj); }); + return; + + // conroller.onChange(function(colorArray) { + // var colorObject = convertColorArrayToObject(colorArray); + // var obj = {}; + // obj[key] = colorObject + // writeVec3ToInterface(obj) + // console.log('color changed, write this to interface' + JSON.stringify(obj)) + // }); + // controllers.push(controller); } function createVec3Folder(category) { @@ -211,7 +242,6 @@ function createVec3Folder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } @@ -257,7 +287,6 @@ function createQuatFolder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } @@ -293,10 +322,27 @@ function createColorFolder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } + +function convertColorObjectToArray(colorObject) { + var colorArray = []; + _.each(colorObject, function(singleColor) { + colorArray.push(singleColor); + }) + return colorArray +} + +function convertColorArrayToObject(colorArray) { + var colorObject = { + red: colorArray[0], + green: colorArray[1], + blue: colorArray[2] + } + return colorObject +} + function writeDataToInterface(property, value) { var data = {}; data[property] = value; @@ -354,7 +400,7 @@ function listenForSettingsUpdates() { if (data.messageType === 'object_update') { _.each(data.objectSettings, function(value, key) { - settings[key] = value; + // settings[key] = value; }); } @@ -409,6 +455,11 @@ function prepareSettingsForExport() { return; } + if(key.indexOf('color')>-1){ + var colorObject = convertColorArrayToObject(settings[key]); + settings[key]=colorObject + } + exportSettings[key] = settings[key]; }) return JSON.stringify(exportSettings); @@ -418,8 +469,8 @@ function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) try { - var importedSettings = JSON.parse(importInput.value); - // importedSettings = importInput.value; + var importedSettings = JSON.parse(importInput.value); + // importedSettings = importInput.value; var keys = _.keys(importedSettings); _.each(keys, function(key) { var shouldIgnore = _.contains(keysToIgnore, key); From 290659b9f6650c01e04721e19b16f4f66989b1bf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 11:46:37 -0700 Subject: [PATCH 363/418] increased lifetime --- examples/closePaint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index fa692e0bbc..136237d4b7 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -146,7 +146,7 @@ function MyController(hand, triggerAction) { y: 50, z: 50 }, - lifetime: 100 + lifetime: 200 }); this.strokePoints = []; this.strokeNormals = []; From d2f4b6e9f0e9b882a47ab839bc2bfde273660620 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 12:21:56 -0700 Subject: [PATCH 364/418] add / remove controller listener methods --- examples/particle_explorer/main.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 6c9d812280..71caf4cafb 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -21,15 +21,19 @@ var Settings = function() { } }; + +var AUTO_UPDATE = false; +var UPDATE_ALL_FREQUENCY = 1000; + var controllers = []; var colorControllers = []; var folders = []; var gui; var settings = new Settings(); var updateInterval; -var AUTO_UPDATE = false; -var UPDATE_ALL_FREQUENCY = 1000; +var currentInputField; +var storedController; var keysToIgnore = [ 'importSettings', 'exportSettings', @@ -465,6 +469,16 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } +function removeListener(key){ + _.each(gui.__listening,function(controller,index){ + if(controller.property===key){ + console.log('CONTROLLER KEY MATCHES REMOVELISTENER KEY') + storedController = controller; + gui.__listening.splice(index,1); + } + }); +} + function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) From 861aa91572d6c56c1f9357b641be9149a283eb47 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 12:27:45 -0700 Subject: [PATCH 365/418] shoot out of the right end of the gun --- examples/toys/ping_pong_gun/pingPongGun.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/ping_pong_gun/pingPongGun.js b/examples/toys/ping_pong_gun/pingPongGun.js index 0a589fb3fb..a980fc1bd3 100644 --- a/examples/toys/ping_pong_gun/pingPongGun.js +++ b/examples/toys/ping_pong_gun/pingPongGun.js @@ -21,7 +21,7 @@ //if the trigger value goes below this value, reload the gun. var RELOAD_THRESHOLD = 0.95; - var GUN_TIP_FWD_OFFSET = -0.55; + var GUN_TIP_FWD_OFFSET = 0.45; var GUN_TIP_UP_OFFSET = 0.040; var GUN_FORCE = 15; var BALL_RESTITUTION = 0.6; @@ -106,7 +106,7 @@ }, shootBall: function(gunProperties) { - var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, -90, 0))); forwardVec = Vec3.normalize(forwardVec); forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); var properties = { From b37bf2b1b68cb191bc8e01760b107a5f0cb22300 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 1 Oct 2015 13:18:22 -0700 Subject: [PATCH 366/418] Remove extra debug --- interface/resources/qml/VrMenu.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/qml/VrMenu.qml b/interface/resources/qml/VrMenu.qml index ef7ae852d4..14a4a449fd 100644 --- a/interface/resources/qml/VrMenu.qml +++ b/interface/resources/qml/VrMenu.qml @@ -196,7 +196,6 @@ Hifi.VrMenu { function insertItem(menu, beforeItem, newMenuItem) { for (var i = 0; i < menu.items.length; ++i) { - console.log(menu.items[i]); if (menu.items[i] === beforeItem) { return menu.insertItem(i, newMenuItem); } From 8453043038fbdd3d7bc1e650fde4e60da334456f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 13:23:51 -0700 Subject: [PATCH 367/418] remove unused variable --- libraries/animation/src/Rig.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9918b09b8c..a3c48fca5f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -625,7 +625,6 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false, 1.0f); - JointState& state = _jointStates[i]; setJointTranslation((int)i, true, poses[i].trans, PRIORITY); } From 09ac01a5e78684fc5ca46d2ae666bdea4b935101 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 1 Oct 2015 13:42:20 -0700 Subject: [PATCH 368/418] remove cruft from old verlet avatar simulation --- interface/src/avatar/SkeletonModel.cpp | 2 +- libraries/animation/src/AnimationHandle.cpp | 1 - libraries/animation/src/JointState.cpp | 89 +-------- libraries/animation/src/JointState.h | 30 +-- libraries/animation/src/Rig.cpp | 80 ++------ libraries/animation/src/Rig.h | 6 +- libraries/physics/src/Constraint.h | 25 --- libraries/render-utils/src/Model.cpp | 54 +----- libraries/render-utils/src/Model.h | 11 -- libraries/shared/src/AngularConstraint.cpp | 202 -------------------- libraries/shared/src/AngularConstraint.h | 54 ------ 11 files changed, 32 insertions(+), 522 deletions(-) delete mode 100644 libraries/physics/src/Constraint.h delete mode 100644 libraries/shared/src/AngularConstraint.cpp delete mode 100644 libraries/shared/src/AngularConstraint.h diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index b1f6e6d8d1..7c2cf43c07 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -320,7 +320,7 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position) float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f; _rig->applyJointRotationDelta(jointIndex, rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), forearmVector), - true, PALM_PRIORITY); + PALM_PRIORITY); } void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index f2d12b398e..93dd965e02 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -181,7 +181,6 @@ void AnimationHandle::applyFrame(float frameIndex) { ceilFrame.rotations.at(i), frameFraction), _priority, - false, _mix); } } diff --git a/libraries/animation/src/JointState.cpp b/libraries/animation/src/JointState.cpp index 9597a46726..0746f65e84 100644 --- a/libraries/animation/src/JointState.cpp +++ b/libraries/animation/src/JointState.cpp @@ -13,16 +13,11 @@ #include -#include #include #include "JointState.h" JointState::~JointState() { - if (_constraint) { - delete _constraint; - _constraint = NULL; - } } void JointState::copyState(const JointState& other) { @@ -35,18 +30,12 @@ void JointState::copyState(const JointState& other) { _distanceToParent = other._distanceToParent; _animationPriority = other._animationPriority; - _visibleTransform = other._visibleTransform; - _visibleRotation = extractRotation(_visibleTransform); - _visibleRotationInConstrainedFrame = other._visibleRotationInConstrainedFrame; - // DO NOT copy _constraint _name = other._name; _isFree = other._isFree; _parentIndex = other._parentIndex; _defaultRotation = other._defaultRotation; _inverseDefaultRotation = other._inverseDefaultRotation; _translation = other._translation; - _rotationMin = other._rotationMin; - _rotationMax = other._rotationMax; _preRotation = other._preRotation; _postRotation = other._postRotation; _preTransform = other._preTransform; @@ -61,8 +50,6 @@ JointState::JointState(const FBXJoint& joint) { _translation = joint.translation; _defaultRotation = joint.rotation; _inverseDefaultRotation = joint.inverseDefaultRotation; - _rotationMin = joint.rotationMin; - _rotationMax = joint.rotationMax; _preRotation = joint.preRotation; _postRotation = joint.postRotation; _preTransform = joint.preTransform; @@ -71,15 +58,6 @@ JointState::JointState(const FBXJoint& joint) { } void JointState::buildConstraint() { - if (_constraint) { - delete _constraint; - _constraint = NULL; - } - if (glm::distance2(glm::vec3(-PI), _rotationMin) > EPSILON || - glm::distance2(glm::vec3(PI), _rotationMax) > EPSILON ) { - // this joint has rotation constraints - _constraint = AngularConstraint::newAngularConstraint(_rotationMin, _rotationMax); - } } glm::quat JointState::getRotation() const { @@ -113,13 +91,6 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT } } -void JointState::computeVisibleTransform(const glm::mat4& parentTransform) { - glm::quat rotationInParentFrame = _preRotation * _visibleRotationInConstrainedFrame * _postRotation; - glm::mat4 transformInParentFrame = _preTransform * glm::mat4_cast(rotationInParentFrame) * _postTransform; - _visibleTransform = parentTransform * glm::translate(_translation) * transformInParentFrame; - _visibleRotation = extractRotation(_visibleTransform); -} - glm::quat JointState::getRotationInBindFrame() const { return getRotation() * _inverseBindRotation; } @@ -128,10 +99,6 @@ glm::quat JointState::getRotationInParentFrame() const { return _preRotation * _rotationInConstrainedFrame * _postRotation; } -glm::quat JointState::getVisibleRotationInParentFrame() const { - return _preRotation * _visibleRotationInConstrainedFrame * _postRotation; -} - void JointState::restoreRotation(float fraction, float priority) { if (priority == _animationPriority || _animationPriority == 0.0f) { setRotationInConstrainedFrameInternal(safeMix(_rotationInConstrainedFrame, _defaultRotation, fraction)); @@ -139,19 +106,16 @@ void JointState::restoreRotation(float fraction, float priority) { } } -void JointState::setRotationInBindFrame(const glm::quat& rotation, float priority, bool constrain) { +void JointState::setRotationInBindFrame(const glm::quat& rotation, float priority) { // rotation is from bind- to model-frame if (priority >= _animationPriority) { glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * rotation * glm::inverse(_inverseBindRotation); - if (constrain && _constraint) { - _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); - } setRotationInConstrainedFrameInternal(targetRotation); _animationPriority = priority; } } -void JointState::setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority, bool constrain) { +void JointState::setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority) { // rotation is from bind- to model-frame if (priority >= _animationPriority) { glm::quat parentRotation = computeParentRotation(); @@ -160,9 +124,6 @@ void JointState::setRotationInModelFrame(const glm::quat& rotationInModelFrame, // R' = Rp * Rpre * r' * Rpost // r' = (Rp * Rpre)^ * R' * Rpost^ glm::quat targetRotation = glm::inverse(parentRotation * _preRotation) * rotationInModelFrame * glm::inverse(_postRotation); - if (constrain && _constraint) { - _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); - } _rotationInConstrainedFrame = glm::normalize(targetRotation); _transformChanged = true; _animationPriority = priority; @@ -174,26 +135,15 @@ void JointState::clearTransformTranslation() { _transform[3][1] = 0.0f; _transform[3][2] = 0.0f; _transformChanged = true; - _visibleTransform[3][0] = 0.0f; - _visibleTransform[3][1] = 0.0f; - _visibleTransform[3][2] = 0.0f; } -void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) { +void JointState::applyRotationDelta(const glm::quat& delta, float priority) { // NOTE: delta is in model-frame if (priority < _animationPriority || delta == glm::quat()) { return; } _animationPriority = priority; glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * delta * getRotation(); - if (!constrain || _constraint == NULL) { - // no constraints - _rotationInConstrainedFrame = targetRotation; - _transformChanged = true; - - _rotation = delta * getRotation(); - return; - } setRotationInConstrainedFrameInternal(targetRotation); } @@ -209,36 +159,17 @@ void JointState::mixRotationDelta(const glm::quat& delta, float mixFactor, float if (mixFactor > 0.0f && mixFactor <= 1.0f) { targetRotation = safeMix(targetRotation, _defaultRotation, mixFactor); } - if (_constraint) { - _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); - } setRotationInConstrainedFrameInternal(targetRotation); } -void JointState::mixVisibleRotationDelta(const glm::quat& delta, float mixFactor) { - // NOTE: delta is in model-frame - glm::quat targetRotation = _visibleRotationInConstrainedFrame * glm::inverse(_visibleRotation) * delta * _visibleRotation; - if (mixFactor > 0.0f && mixFactor <= 1.0f) { - targetRotation = safeMix(targetRotation, _rotationInConstrainedFrame, mixFactor); - } - setVisibleRotationInConstrainedFrame(targetRotation); -} - glm::quat JointState::computeParentRotation() const { // R = Rp * Rpre * r * Rpost // Rp = R * (Rpre * r * Rpost)^ return getRotation() * glm::inverse(_preRotation * _rotationInConstrainedFrame * _postRotation); } -glm::quat JointState::computeVisibleParentRotation() const { - return _visibleRotation * glm::inverse(_preRotation * _visibleRotationInConstrainedFrame * _postRotation); -} - -void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float priority, bool constrain, float mix) { +void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float priority, float mix) { if (priority >= _animationPriority || _animationPriority == 0.0f) { - if (constrain && _constraint) { - _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); - } auto rotation = (mix == 1.0f) ? targetRotation : safeMix(getRotationInConstrainedFrame(), targetRotation, mix); setRotationInConstrainedFrameInternal(rotation); _animationPriority = priority; @@ -255,12 +186,6 @@ void JointState::setRotationInConstrainedFrameInternal(const glm::quat& targetRo } } -void JointState::setVisibleRotationInConstrainedFrame(const glm::quat& targetRotation) { - glm::quat parentRotation = computeVisibleParentRotation(); - _visibleRotationInConstrainedFrame = targetRotation; - _visibleRotation = parentRotation * _preRotation * _visibleRotationInConstrainedFrame * _postRotation; -} - bool JointState::rotationIsDefault(const glm::quat& rotation, float tolerance) const { glm::quat defaultRotation = _defaultRotation; return glm::abs(rotation.x - defaultRotation.x) < tolerance && @@ -277,9 +202,3 @@ glm::quat JointState::getDefaultRotationInParentFrame() const { const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { return _translation; } - -void JointState::slaveVisibleTransform() { - _visibleTransform = _transform; - _visibleRotation = getRotation(); - _visibleRotationInConstrainedFrame = _rotationInConstrainedFrame; -} diff --git a/libraries/animation/src/JointState.h b/libraries/animation/src/JointState.h index 07ed010104..eee8863e6f 100644 --- a/libraries/animation/src/JointState.h +++ b/libraries/animation/src/JointState.h @@ -22,8 +22,6 @@ const float DEFAULT_PRIORITY = 3.0f; -class AngularConstraint; - class JointState { public: JointState() {} @@ -39,11 +37,6 @@ public: // but _rotation will be asynchronously extracted void computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged = true, bool synchronousRotationCompute = false); - void computeVisibleTransform(const glm::mat4& parentTransform); - const glm::mat4& getVisibleTransform() const { return _visibleTransform; } - glm::quat getVisibleRotation() const { return _visibleRotation; } - glm::vec3 getVisiblePosition() const { return extractTranslation(_visibleTransform); } - const glm::mat4& getTransform() const { return _transform; } void resetTransformChanged() { _transformChanged = false; } bool getTransformChanged() const { return _transformChanged; } @@ -55,14 +48,13 @@ public: glm::quat getRotationInBindFrame() const; glm::quat getRotationInParentFrame() const; - glm::quat getVisibleRotationInParentFrame() const; const glm::vec3& getPositionInParentFrame() const { return _positionInParentFrame; } float getDistanceToParent() const { return _distanceToParent; } int getParentIndex() const { return _parentIndex; } /// \param delta is in the model-frame - void applyRotationDelta(const glm::quat& delta, bool constrain = true, float priority = 1.0f); + void applyRotationDelta(const glm::quat& delta, float priority = 1.0f); /// Applies delta rotation to joint but mixes a little bit of the default pose as well. /// This helps keep an IK solution stable. @@ -70,7 +62,6 @@ public: /// \param mixFactor fraction in range [0,1] of how much default pose to blend in (0 is none, 1 is all) /// \param priority priority level of this animation blend void mixRotationDelta(const glm::quat& delta, float mixFactor, float priority = 1.0f); - void mixVisibleRotationDelta(const glm::quat& delta, float mixFactor); /// Blends a fraciton of default pose into joint rotation. /// \param fraction fraction in range [0,1] of how much default pose to blend in (0 is none, 1 is all) @@ -80,17 +71,15 @@ public: /// \param rotation is from bind- to model-frame /// computes and sets new _rotationInConstrainedFrame /// NOTE: the JointState's model-frame transform/rotation are NOT updated! - void setRotationInBindFrame(const glm::quat& rotation, float priority, bool constrain = false); + void setRotationInBindFrame(const glm::quat& rotation, float priority); /// \param rotationInModelRame is in model-frame /// computes and sets new _rotationInConstrainedFrame to match rotationInModelFrame /// NOTE: the JointState's model-frame transform/rotation are NOT updated! - void setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority, bool constrain); + void setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority); - void setRotationInConstrainedFrame(glm::quat targetRotation, float priority, bool constrain = false, float mix = 1.0f); - void setVisibleRotationInConstrainedFrame(const glm::quat& targetRotation); + void setRotationInConstrainedFrame(glm::quat targetRotation, float priority, float mix = 1.0f); const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; } - const glm::quat& getVisibleRotationInConstrainedFrame() const { return _visibleRotationInConstrainedFrame; } bool rotationIsDefault(const glm::quat& rotation, float tolerance = EPSILON) const; @@ -100,15 +89,11 @@ public: void clearTransformTranslation(); - void slaveVisibleTransform(); - /// \return parent model-frame rotation // (used to keep _rotation consistent when modifying _rotationInWorldFrame directly) glm::quat computeParentRotation() const; - glm::quat computeVisibleParentRotation() const; void setTransform(const glm::mat4& transform) { _transform = transform; } - void setVisibleTransform(const glm::mat4& transform) { _visibleTransform = transform; } const glm::vec3& getTranslation() const { return _translation; } const glm::mat4& getPreTransform() const { return _preTransform; } @@ -132,24 +117,17 @@ private: glm::vec3 _positionInParentFrame {0.0f}; // only changes when the Model is scaled float _animationPriority {0.0f}; // the priority of the animation affecting this joint float _distanceToParent {0.0f}; - AngularConstraint* _constraint{nullptr}; // JointState owns its AngularConstraint glm::mat4 _transform; // joint- to model-frame glm::quat _rotation; // joint- to model-frame glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied - glm::mat4 _visibleTransform; - glm::quat _visibleRotation; - glm::quat _visibleRotationInConstrainedFrame; - glm::quat _defaultRotation; // Not necessarilly bind rotation. See FBXJoint transform/bindTransform glm::quat _inverseDefaultRotation; glm::vec3 _translation; QString _name; int _parentIndex; bool _isFree; - glm::vec3 _rotationMin; - glm::vec3 _rotationMax; glm::quat _preRotation; glm::quat _postRotation; glm::mat4 _preTransform; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 1e512ee767..7866060cf3 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -224,14 +224,6 @@ void Rig::initJointStates(QVector states, glm::mat4 rootTransform, _rightShoulderJointIndex = rightShoulderJointIndex; initJointTransforms(rootTransform); - - int numStates = _jointStates.size(); - for (int i = 0; i < numStates; ++i) { - _jointStates[i].buildConstraint(); - } - for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].slaveVisibleTransform(); - } } // We could build and cache a dictionary, too.... @@ -293,15 +285,6 @@ bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { return !state.rotationIsDefault(rotation); } -bool Rig::getVisibleJointState(int index, glm::quat& rotation) const { - if (index == -1 || index >= _jointStates.size()) { - return false; - } - const JointState& state = _jointStates.at(index); - rotation = state.getVisibleRotationInConstrainedFrame(); - return !state.rotationIsDefault(rotation); -} - void Rig::clearJointState(int index) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; @@ -392,25 +375,6 @@ bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm: return true; } - -bool Rig::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position, - glm::vec3 translation, glm::quat rotation) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return false; - } - // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getVisiblePosition(); - return true; -} - -bool Rig::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result, glm::quat rotation) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return false; - } - result = rotation * _jointStates[jointIndex].getVisibleRotation(); - return true; -} - glm::mat4 Rig::getJointTransform(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return glm::mat4(); @@ -418,13 +382,6 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const { return _jointStates[jointIndex].getTransform(); } -glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return glm::mat4(); - } - return _jointStates[jointIndex].getVisibleTransform(); -} - void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation) { glm::vec3 front = worldRotation * IDENTITY_FRONT; @@ -596,7 +553,7 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { // copy poses into jointStates const float PRIORITY = 1.0f; for (size_t i = 0; i < poses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false, 1.0f); + setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, 1.0f); } } else { @@ -719,7 +676,7 @@ bool Rig::setJointPosition(int jointIndex, const glm::vec3& position, const glm: 1.0f / (combinedWeight + 1.0f)); } } - state.applyRotationDelta(combinedDelta, true, priority); + state.applyRotationDelta(combinedDelta, priority); glm::quat actualDelta = state.getRotation() * glm::inverse(oldCombinedRotation); endPosition = actualDelta * jointVector + jointPosition; if (useRotation) { @@ -838,11 +795,9 @@ void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::q // Apply the rotation delta. glm::quat oldNextRotation = nextState.getRotation(); - float mixFactor = 0.05f; - nextState.applyRotationDelta(deltaRotation, mixFactor, priority); + nextState.applyRotationDelta(deltaRotation, priority); - // measure the result of the rotation which may have been modified by - // blending and constraints + // measure the result of the rotation which may have been modified by blending glm::quat actualDelta = nextState.getRotation() * glm::inverse(oldNextRotation); endPosition = pivot + actualDelta * leverArm; } @@ -861,7 +816,7 @@ void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::q } while (numIterations < MAX_ITERATION_COUNT && distanceToGo > ACCEPTABLE_IK_ERROR); // set final rotation of the end joint - endState.setRotationInModelFrame(targetRotation, priority, true); + endState.setRotationInModelFrame(targetRotation, priority); } bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, const QVector& freeLineage) { @@ -889,13 +844,13 @@ float Rig::getLimbLength(int jointIndex, const QVector& freeLineage, return length; } -glm::quat Rig::setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority, bool constrain) { +glm::quat Rig::setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority) { glm::quat endRotation; if (jointIndex == -1 || _jointStates.isEmpty()) { return endRotation; } JointState& state = _jointStates[jointIndex]; - state.setRotationInBindFrame(rotation, priority, constrain); + state.setRotationInBindFrame(rotation, priority); endRotation = state.getRotationInBindFrame(); return endRotation; } @@ -907,13 +862,13 @@ glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) { return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame(); } -glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain, float mix) { +glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, float mix) { glm::quat endRotation; if (jointIndex == -1 || _jointStates.isEmpty()) { return endRotation; } JointState& state = _jointStates[jointIndex]; - state.setRotationInConstrainedFrame(targetRotation, priority, constrain, mix); + state.setRotationInConstrainedFrame(targetRotation, priority, mix); endRotation = state.getRotationInConstrainedFrame(); return endRotation; } @@ -926,30 +881,17 @@ bool Rig::getJointRotationInConstrainedFrame(int jointIndex, glm::quat& quatOut) return true; } -void Rig::updateVisibleJointStates() { - for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].slaveVisibleTransform(); - } -} - void Rig::clearJointStatePriorities() { for (int i = 0; i < _jointStates.size(); i++) { _jointStates[i].setAnimationPriority(0.0f); } } -void Rig::setJointVisibleTransform(int jointIndex, glm::mat4 newTransform) { - if (jointIndex == -1 || jointIndex >= _jointStates.size()) { - return; - } - _jointStates[jointIndex].setVisibleTransform(newTransform); -} - -void Rig::applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority) { +void Rig::applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority) { if (jointIndex == -1 || _jointStates.isEmpty()) { return; } - _jointStates[jointIndex].applyRotationDelta(delta, constrain, priority); + _jointStates[jointIndex].applyRotationDelta(delta, priority); } glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 6dad58db87..8ddc0c9f6d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -129,7 +129,7 @@ public: void clearJointTransformTranslation(int jointIndex); void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; - void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority); + void applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority); JointState getJointState(int jointIndex) const; // XXX bool getVisibleJointState(int index, glm::quat& rotation) const; void clearJointState(int index); @@ -165,10 +165,10 @@ public: float getLimbLength(int jointIndex, const QVector& freeLineage, const glm::vec3 scale, const QVector& fbxJoints) const; - glm::quat setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority, bool constrain = false); + glm::quat setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority); glm::vec3 getJointDefaultTranslationInConstrainedFrame(int jointIndex); glm::quat setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, - float priority, bool constrain = false, float mix = 1.0f); + float priority, float mix = 1.0f); bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; glm::quat getJointDefaultRotationInParentFrame(int jointIndex); void updateVisibleJointStates(); diff --git a/libraries/physics/src/Constraint.h b/libraries/physics/src/Constraint.h deleted file mode 100644 index ed97d6cc73..0000000000 --- a/libraries/physics/src/Constraint.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Constraint.h -// libraries/physics/src -// -// Created by Andrew Meadows 2014.07.24 -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_Constraint_h -#define hifi_Constraint_h - -class Constraint { -public: - Constraint() {} - virtual ~Constraint() {} - - /// Enforce contraint by moving relevant points. - /// \return max distance of point movement - virtual float enforce() = 0; -}; - -#endif // hifi_Constraint_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2f16259f89..90dbe6524c 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -68,7 +68,6 @@ Model::Model(RigPointer rig, QObject* parent) : _scaledToFit(false), _snapModelToRegistrationPoint(false), _snappedToRegistrationPoint(false), - _showTrueJointTransforms(true), _cauterizeBones(false), _pupilDilation(0.0f), _url(HTTP_INVALID_COM), @@ -998,10 +997,6 @@ bool Model::getJointState(int index, glm::quat& rotation) const { return _rig->getJointStateRotation(index, rotation); } -bool Model::getVisibleJointState(int index, glm::quat& rotation) const { - return _rig->getVisibleJointState(index, rotation); -} - void Model::clearJointState(int index) { _rig->clearJointState(index); } @@ -1083,14 +1078,6 @@ bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const return _rig->getJointCombinedRotation(jointIndex, rotation, _rotation); } -bool Model::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const { - return _rig->getVisibleJointPositionInWorldFrame(jointIndex, position, _translation, _rotation); -} - -bool Model::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const { - return _rig->getVisibleJointRotationInWorldFrame(jointIndex, rotation, _rotation); -} - QStringList Model::getJointNames() const { if (QThread::currentThread() != thread()) { QStringList result; @@ -1294,33 +1281,17 @@ void Model::updateClusterMatrices() { for (int i = 0; i < _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); - if (_showTrueJointTransforms) { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); - state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; + for (int j = 0; j < mesh.clusters.size(); j++) { + const FBXCluster& cluster = mesh.clusters.at(j); + auto jointMatrix = _rig->getJointTransform(cluster.jointIndex); + state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; - // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. - if (!_cauterizeBoneSet.empty()) { - if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { - jointMatrix = cauterizeMatrix; - } - state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; - } - } - } else { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - auto jointMatrix = _rig->getJointVisibleTransform(cluster.jointIndex); // differs from above only in using get...VisibleTransform - state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; - - // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. - if (!_cauterizeBoneSet.empty()) { - if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { - jointMatrix = cauterizeMatrix; - } - state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; + // as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty. + if (!_cauterizeBoneSet.empty()) { + if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) { + jointMatrix = cauterizeMatrix; } + state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix; } } } @@ -1533,13 +1504,6 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe, args, locations); - { - if (!_showTrueJointTransforms) { - PerformanceTimer perfTimer("_rig->updateVisibleJointStates()"); - _rig->updateVisibleJointStates(); - } // else no need to update visible transforms - } - // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown // to false to rebuild out mesh groups. if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index e069b10954..2620310857 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -221,26 +221,17 @@ protected: /// \return whether or not the joint state is "valid" (that is, non-default) bool getJointState(int index, glm::quat& rotation) const; - /// Fetches the visible joint state at the specified index. - /// \return whether or not the joint state is "valid" (that is, non-default) - bool getVisibleJointState(int index, glm::quat& rotation) const; - /// Clear the joint states void clearJointState(int index); /// Returns the index of the last free ancestor of the indexed joint, or -1 if not found. int getLastFreeJointIndex(int jointIndex) const; - bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const; - bool getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const; - /// \param jointIndex index of joint in model structure /// \param position[out] position of joint in model-frame /// \return true if joint exists bool getJointPosition(int jointIndex, glm::vec3& position) const; - void setShowTrueJointTransforms(bool show) { _showTrueJointTransforms = show; } - QSharedPointer _geometry; void setGeometry(const QSharedPointer& newGeometry); @@ -259,8 +250,6 @@ protected: bool _snappedToRegistrationPoint; /// are we currently snapped to a registration point glm::vec3 _registrationPoint = glm::vec3(0.5f); /// the point in model space our center is snapped to - bool _showTrueJointTransforms; - class MeshState { public: QVector clusterMatrices; diff --git a/libraries/shared/src/AngularConstraint.cpp b/libraries/shared/src/AngularConstraint.cpp deleted file mode 100644 index 62cdca67fd..0000000000 --- a/libraries/shared/src/AngularConstraint.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// -// AngularConstraint.cpp -// interface/src/renderer -// -// Created by Andrew Meadows on 2014.05.30 -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "AngularConstraint.h" -#include "GLMHelpers.h" -#include "NumericalConstants.h" - -// helper function -/// \param angle radian angle to be clamped within angleMin and angleMax -/// \param angleMin minimum value -/// \param angleMax maximum value -/// \return value between minAngle and maxAngle closest to angle -float clampAngle(float angle, float angleMin, float angleMax) { - float minDistance = angle - angleMin; - float maxDistance = angle - angleMax; - if (maxDistance > 0.0f) { - minDistance = glm::min(minDistance, angleMin + TWO_PI - angle); - angle = (minDistance < maxDistance) ? angleMin : angleMax; - } else if (minDistance < 0.0f) { - maxDistance = glm::max(maxDistance, angleMax - TWO_PI - angle); - angle = (minDistance > maxDistance) ? angleMin : angleMax; - } - return angle; -} - -// static -AngularConstraint* AngularConstraint::newAngularConstraint(const glm::vec3& minAngles, const glm::vec3& maxAngles) { - float minDistance2 = glm::distance2(minAngles, glm::vec3(-PI, -PI, -PI)); - float maxDistance2 = glm::distance2(maxAngles, glm::vec3(PI, PI, PI)); - if (minDistance2 < EPSILON && maxDistance2 < EPSILON) { - // no constraint - return NULL; - } - // count the zero length elements - glm::vec3 rangeAngles = maxAngles - minAngles; - int pivotIndex = -1; - int numZeroes = 0; - for (int i = 0; i < 3; ++i) { - if (rangeAngles[i] < EPSILON) { - ++numZeroes; - } else { - pivotIndex = i; - } - } - if (numZeroes == 2) { - // this is a hinge - int forwardIndex = (pivotIndex + 1) % 3; - glm::vec3 forwardAxis(0.0f); - forwardAxis[forwardIndex] = 1.0f; - glm::vec3 rotationAxis(0.0f); - rotationAxis[pivotIndex] = 1.0f; - return new HingeConstraint(forwardAxis, rotationAxis, minAngles[pivotIndex], maxAngles[pivotIndex]); - } else if (numZeroes == 0) { - // approximate the angular limits with a cone roller - // we assume the roll is about z - glm::vec3 middleAngles = 0.5f * (maxAngles + minAngles); - glm::quat yaw = glm::angleAxis(middleAngles[1], glm::vec3(0.0f, 1.0f, 0.0f)); - glm::quat pitch = glm::angleAxis(middleAngles[0], glm::vec3(1.0f, 0.0f, 0.0f)); - glm::vec3 coneAxis = pitch * yaw * glm::vec3(0.0f, 0.0f, 1.0f); - // the coneAngle is half the average range of the two non-roll rotations - glm::vec3 range = maxAngles - minAngles; - float coneAngle = 0.25f * (range[0] + range[1]); - return new ConeRollerConstraint(coneAngle, coneAxis, minAngles.z, maxAngles.z); - } - return NULL; -} - -bool AngularConstraint::softClamp(glm::quat& targetRotation, const glm::quat& oldRotation, float mixFraction) { - glm::quat clampedTarget = targetRotation; - bool clamped = clamp(clampedTarget); - if (clamped) { - // check if oldRotation is also clamped - glm::quat clampedOld = oldRotation; - bool clamped2 = clamp(clampedOld); - if (clamped2) { - // oldRotation is already beyond the constraint - // we clamp again midway between targetRotation and clamped oldPosition - clampedTarget = glm::shortMix(clampedOld, targetRotation, mixFraction); - // and then clamp that - clamp(clampedTarget); - } - // finally we mix targetRotation with the clampedTarget - targetRotation = glm::shortMix(clampedTarget, targetRotation, mixFraction); - } - return clamped; -} - -HingeConstraint::HingeConstraint(const glm::vec3& forwardAxis, const glm::vec3& rotationAxis, float minAngle, float maxAngle) - : _minAngle(minAngle), _maxAngle(maxAngle) { - assert(_minAngle < _maxAngle); - // we accept the rotationAxis direction - assert(glm::length(rotationAxis) > EPSILON); - _rotationAxis = glm::normalize(rotationAxis); - // but we compute the final _forwardAxis - glm::vec3 otherAxis = glm::cross(_rotationAxis, forwardAxis); - assert(glm::length(otherAxis) > EPSILON); - _forwardAxis = glm::normalize(glm::cross(otherAxis, _rotationAxis)); -} - -// virtual -bool HingeConstraint::clamp(glm::quat& rotation) const { - glm::vec3 forward = rotation * _forwardAxis; - forward -= glm::dot(forward, _rotationAxis) * _rotationAxis; - float length = glm::length(forward); - if (length < EPSILON) { - // infinite number of solutions ==> choose the middle of the contrained range - rotation = glm::angleAxis(0.5f * (_minAngle + _maxAngle), _rotationAxis); - return true; - } - forward /= length; - float sign = (glm::dot(glm::cross(_forwardAxis, forward), _rotationAxis) > 0.0f ? 1.0f : -1.0f); - //float angle = sign * acos(glm::dot(forward, _forwardAxis) / length); - float angle = sign * acosf(glm::dot(forward, _forwardAxis)); - glm::quat newRotation = glm::angleAxis(clampAngle(angle, _minAngle, _maxAngle), _rotationAxis); - if (fabsf(1.0f - glm::dot(newRotation, rotation)) > EPSILON * EPSILON) { - rotation = newRotation; - return true; - } - return false; -} - -bool HingeConstraint::softClamp(glm::quat& targetRotation, const glm::quat& oldRotation, float mixFraction) { - // the hinge works best without a soft clamp - return clamp(targetRotation); -} - -ConeRollerConstraint::ConeRollerConstraint(float coneAngle, const glm::vec3& coneAxis, float minRoll, float maxRoll) - : _coneAngle(coneAngle), _minRoll(minRoll), _maxRoll(maxRoll) { - assert(_maxRoll >= _minRoll); - float axisLength = glm::length(coneAxis); - assert(axisLength > EPSILON); - _coneAxis = coneAxis / axisLength; -} - -// virtual -bool ConeRollerConstraint::clamp(glm::quat& rotation) const { - bool applied = false; - glm::vec3 rotatedAxis = rotation * _coneAxis; - glm::vec3 perpAxis = glm::cross(rotatedAxis, _coneAxis); - float perpAxisLength = glm::length(perpAxis); - if (perpAxisLength > EPSILON) { - perpAxis /= perpAxisLength; - // enforce the cone - float angle = acosf(glm::dot(rotatedAxis, _coneAxis)); - if (angle > _coneAngle) { - rotation = glm::angleAxis(angle - _coneAngle, perpAxis) * rotation; - rotatedAxis = rotation * _coneAxis; - applied = true; - } - } else { - // the rotation is 100% roll - // there is no obvious perp axis so we must pick one - perpAxis = rotatedAxis; - // find the first non-zero element: - float iValue = 0.0f; - int i = 0; - for (i = 0; i < 3; ++i) { - if (fabsf(perpAxis[i]) > EPSILON) { - iValue = perpAxis[i]; - break; - } - } - assert(i != 3); - // swap or negate the next element - int j = (i + 1) % 3; - float jValue = perpAxis[j]; - if (fabsf(jValue - iValue) > EPSILON) { - perpAxis[i] = jValue; - perpAxis[j] = iValue; - } else { - perpAxis[i] = -iValue; - } - perpAxis = glm::cross(perpAxis, rotatedAxis); - perpAxisLength = glm::length(perpAxis); - assert(perpAxisLength > EPSILON); - perpAxis /= perpAxisLength; - } - // measure the roll - // NOTE: perpAxis is perpendicular to both _coneAxis and rotatedConeAxis, so we can - // rotate it again and we'll end up with an something that has only been rolled. - glm::vec3 rolledPerpAxis = rotation * perpAxis; - float sign = glm::dot(rotatedAxis, glm::cross(perpAxis, rolledPerpAxis)) > 0.0f ? 1.0f : -1.0f; - float roll = sign * angleBetween(rolledPerpAxis, perpAxis); - if (roll < _minRoll || roll > _maxRoll) { - float clampedRoll = clampAngle(roll, _minRoll, _maxRoll); - rotation = glm::normalize(glm::angleAxis(clampedRoll - roll, rotatedAxis) * rotation); - applied = true; - } - return applied; -} - - diff --git a/libraries/shared/src/AngularConstraint.h b/libraries/shared/src/AngularConstraint.h deleted file mode 100644 index 74d3fdb82b..0000000000 --- a/libraries/shared/src/AngularConstraint.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// AngularConstraint.h -// interface/src/renderer -// -// Created by Andrew Meadows on 2014.05.30 -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_AngularConstraint_h -#define hifi_AngularConstraint_h - -#include - -class AngularConstraint { -public: - /// \param minAngles minumum euler angles for the constraint - /// \param maxAngles minumum euler angles for the constraint - /// \return pointer to new AngularConstraint of the right type or NULL if none could be made - static AngularConstraint* newAngularConstraint(const glm::vec3& minAngles, const glm::vec3& maxAngles); - - AngularConstraint() {} - virtual ~AngularConstraint() {} - virtual bool clamp(glm::quat& rotation) const = 0; - virtual bool softClamp(glm::quat& targetRotation, const glm::quat& oldRotation, float mixFraction); -protected: -}; - -class HingeConstraint : public AngularConstraint { -public: - HingeConstraint(const glm::vec3& forwardAxis, const glm::vec3& rotationAxis, float minAngle, float maxAngle); - virtual bool clamp(glm::quat& rotation) const; - virtual bool softClamp(glm::quat& targetRotation, const glm::quat& oldRotation, float mixFraction); -protected: - glm::vec3 _forwardAxis; - glm::vec3 _rotationAxis; - float _minAngle; - float _maxAngle; -}; - -class ConeRollerConstraint : public AngularConstraint { -public: - ConeRollerConstraint(float coneAngle, const glm::vec3& coneAxis, float minRoll, float maxRoll); - virtual bool clamp(glm::quat& rotation) const; -private: - float _coneAngle; - glm::vec3 _coneAxis; - float _minRoll; - float _maxRoll; -}; - -#endif // hifi_AngularConstraint_h From 8bfd38ce7c6ce216a52acfc0b27fe9cb2a403251 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 1 Oct 2015 14:12:32 -0700 Subject: [PATCH 369/418] FBXReader: When the animation has no animation curve use the joint's default position. --- libraries/fbx/src/FBXReader.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 297502d7a1..0c738c5a5b 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1306,17 +1306,18 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS AnimationCurve yPosCurve = animationCurves.value(yComponents.value(translationID)); AnimationCurve zPosCurve = animationCurves.value(zComponents.value(translationID)); - glm::vec3 defaultValues = glm::degrees(safeEulerAngles(joint.rotation)); + glm::vec3 defaultRotValues = glm::degrees(safeEulerAngles(joint.rotation)); + glm::vec3 defaultPosValues = joint.translation; for (int i = 0; i < frameCount; i++) { geometry.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3( - xRotCurve.values.isEmpty() ? defaultValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), - yRotCurve.values.isEmpty() ? defaultValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), - zRotCurve.values.isEmpty() ? defaultValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); + xRotCurve.values.isEmpty() ? defaultRotValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), + yRotCurve.values.isEmpty() ? defaultRotValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), + zRotCurve.values.isEmpty() ? defaultRotValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); geometry.animationFrames[i].translations[jointIndex] = glm::vec3( - xPosCurve.values.isEmpty() ? defaultValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), - yPosCurve.values.isEmpty() ? defaultValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), - zPosCurve.values.isEmpty() ? defaultValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); + xPosCurve.values.isEmpty() ? defaultPosValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), + yPosCurve.values.isEmpty() ? defaultPosValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), + zPosCurve.values.isEmpty() ? defaultPosValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); } } From 7ee26c5d4a8366b2f3399b2bcbe1e40108ce0176 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:26:22 -0700 Subject: [PATCH 370/418] tweaked settings --- examples/closePaint.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index 136237d4b7..6590d7e14e 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -15,13 +15,13 @@ var RIGHT_HAND = 1; var LEFT_HAND = 0; -var MIN_POINT_DISTANCE = 0.01; +var MIN_POINT_DISTANCE = 0.02; var MAX_POINT_DISTANCE = 0.5; var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; -var TRIGGER_ON_VALUE = 0.1; +var TRIGGER_ON_VALUE = 0.3; var MAX_DISTANCE = 10; @@ -35,8 +35,8 @@ var LEFT_2_ACTION = 16; var HUE_INCREMENT = 0.02; -var MIN_STROKE_WIDTH = 0.005; -var MAX_STROKE_WIDTH = 0.03; +var MIN_STROKE_WIDTH = 0.002; +var MAX_STROKE_WIDTH = 0.04; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -196,7 +196,7 @@ function MyController(hand, triggerAction) { if (this.tryPainting) { this.canPaint = true; } - this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); laserSize += this.currentStrokeWidth/2; Overlays.editOverlay(this.laserPointer, { From 5aef7475d6c2f8d2ad6d107b7083ce24a19da320 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:42:51 -0700 Subject: [PATCH 371/418] Sound position updates every frame based on new position of can --- examples/toys/sprayPaintCan.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 18063474a0..dec6a8976a 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -99,7 +99,6 @@ } this.disableStream = function() { - print("DEKETE STEREAAAM") Entities.deleteEntity(this.paintStream); this.paintStream = null; this.sprayInjector.stop(); @@ -125,6 +124,8 @@ position: position, emitOrientation: forwardQuat, }); + this.sprayInjector.setOptions({position: position}); + } From 55c6b9d9c45b59a2279cb37d75d7c15a05e16ca6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:57:03 -0700 Subject: [PATCH 372/418] Added collision sound to blocks --- examples/toys/masterResetEntity.js | 2 ++ examples/toys/sprayPaintCan.js | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index f087d77929..4750b5657b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -743,6 +743,7 @@ function createPillow(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; var NUM_BLOCKS_PER_COLOR = 4; var i, j; @@ -799,6 +800,7 @@ function createBlocks(position) { name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, + collisionSoundURL: collisionSoundURL, gravity: { x: 0, y: -2.5, diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index dec6a8976a..4716885ac3 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -129,9 +129,6 @@ } - - - this.preload = function(entityId) { this.spraying = false; this.entityId = entityId; From 4a7e3c66bd80eb1dbe2b6dc6ad7b2151d0276e9f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 15:05:25 -0700 Subject: [PATCH 373/418] Update createPingPongGun.js use relative paths --- examples/toys/ping_pong_gun/createPingPongGun.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/toys/ping_pong_gun/createPingPongGun.js b/examples/toys/ping_pong_gun/createPingPongGun.js index d8509d8a63..4b7ed27643 100644 --- a/examples/toys/ping_pong_gun/createPingPongGun.js +++ b/examples/toys/ping_pong_gun/createPingPongGun.js @@ -9,8 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /*global MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ -Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); - +Script.include("../../utilities.js"); var scriptURL = Script.resolvePath('pingPongGun.js'); @@ -41,4 +40,4 @@ var pingPongGun = Entities.addEntity({ function cleanUp() { Entities.deleteEntity(pingPongGun); } -Script.scriptEnding.connect(cleanUp); \ No newline at end of file +Script.scriptEnding.connect(cleanUp); From e1b720d338b9acd15862340dd4ea2ef193e58a68 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:18:44 -0700 Subject: [PATCH 374/418] Moved some functions to utils, fixed formatting --- examples/closePaint.js | 490 ++++++++++++++++-------------------- examples/libraries/utils.js | 66 +++++ 2 files changed, 279 insertions(+), 277 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index 6590d7e14e..d9f70aab3c 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/utils.js"); + var RIGHT_HAND = 1; var LEFT_HAND = 0; @@ -44,310 +46,244 @@ var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.g function MyController(hand, triggerAction) { - this.hand = hand; - this.strokes = []; - this.painting = false; - this.currentStrokeWidth = MIN_STROKE_WIDTH; - - if (this.hand === RIGHT_HAND) { - this.getHandPosition = MyAvatar.getRightPalmPosition; - this.getHandRotation = MyAvatar.getRightPalmRotation; - } else { - this.getHandPosition = MyAvatar.getLeftPalmPosition; - this.getHandRotation = MyAvatar.getLeftPalmRotation; - } - - this.triggerAction = triggerAction; - this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; - this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; - - - this.strokeColor = { - h: 0.8, - s: 0.8, - l: 0.4 - }; - - - this.laserPointer = Overlays.addOverlay("circle3d", { - color: hslToRgb(this.strokeColor), - solid: true, - position: center - }) - this.triggerValue = 0; - this.prevTriggerValue = 0; - var _this = this; - - this.update = function() { - this.updateControllerState() - this.search(); - if (this.canPaint === true) { - this.paint(this.intersection.intersection, this.intersection.surfaceNormal); - } - }; - - this.paint = function(position, normal) { - if (this.painting === false) { - if (this.oldPosition) { - this.newStroke(this.oldPosition); - } else { - this.newStroke(position); - } - this.painting = true; - } - - - - var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting - - var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); - if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { - //need a minimum distance to avoid binormal NANs - return; - } - if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { - //Prevents drawing lines accross models - this.painting = false; - return; - } - if (this.strokePoints.length === 0) { - localPoint = { - x: 0, - y: 0, - z: 0 - }; - } - - this.strokePoints.push(localPoint); - this.strokeNormals.push(normal); - this.strokeWidths.push(this.currentStrokeWidth); - Entities.editEntity(this.currentStroke, { - linePoints: this.strokePoints, - normals: this.strokeNormals, - strokeWidths: this.strokeWidths - }); - if (this.strokePoints.length === MAX_POINTS_PER_LINE) { - this.painting = false; - return; - } - this.oldPosition = position - } - - this.newStroke = function(position) { - this.strokeBasePosition = position; - this.currentStroke = Entities.addEntity({ - position: position, - type: "PolyLine", - color: hslToRgb(this.strokeColor), - dimensions: { - x: 50, - y: 50, - z: 50 - }, - lifetime: 200 - }); - this.strokePoints = []; - this.strokeNormals = []; - this.strokeWidths = []; - - this.strokes.push(this.currentStroke); - - } - - this.updateControllerState = function() { - this.triggerValue = Controller.getActionValue(this.triggerAction); - if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { - this.squeeze(); - } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { - this.release() - } - - this.prevTriggerValue = this.triggerValue; - } - - this.squeeze = function() { - this.tryPainting = true; - - } - this.release = function() { + this.hand = hand; + this.strokes = []; this.painting = false; - this.tryPainting = false; - this.canPaint = false; - this.oldPosition = null; - } - this.search = function() { + this.currentStrokeWidth = MIN_STROKE_WIDTH; - // the trigger is being pressed, do a ray test - var handPosition = this.getHandPosition(); - var pickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + } else { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + + this.triggerAction = triggerAction; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; + + + this.strokeColor = { + h: 0.8, + s: 0.8, + l: 0.4 }; - this.intersection = Entities.findRayIntersection(pickRay, true); - if (this.intersection.intersects) { - var distance = Vec3.distance(handPosition, this.intersection.intersection); - if (distance < MAX_DISTANCE) { - var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); - if (this.tryPainting) { - this.canPaint = true; + this.laserPointer = Overlays.addOverlay("circle3d", { + color: hslToRgb(this.strokeColor), + solid: true, + position: center + }); + this.triggerValue = 0; + this.prevTriggerValue = 0; + var _this = this; + + this.update = function() { + this.updateControllerState(); + this.search(); + if (this.canPaint === true) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); } - this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); - var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); - laserSize += this.currentStrokeWidth/2; + }; + + this.paint = function(position, normal) { + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if (this.strokePoints.length === 0) { + localPoint = { + x: 0, + y: 0, + z: 0 + }; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(normal); + this.strokeWidths.push(this.currentStrokeWidth); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position; + } + + this.newStroke = function(position) { + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: hslToRgb(this.strokeColor), + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 200 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + + } + + this.updateControllerState = function() { + this.triggerValue = Controller.getActionValue(this.triggerAction); + if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.squeeze(); + } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + this.release(); + } + + this.prevTriggerValue = this.triggerValue; + } + + this.squeeze = function() { + this.tryPainting = true; + + } + this.release = function() { + this.painting = false; + this.tryPainting = false; + this.canPaint = false; + this.oldPosition = null; + } + this.search = function() { + + // the trigger is being pressed, do a ray test + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + + + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); + if (this.tryPainting) { + this.canPaint = true; + } + this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + var laserSize = map(distance, 1, MAX_DISTANCE, 0.01, 0.1); + laserSize += this.currentStrokeWidth / 2; + Overlays.editOverlay(this.laserPointer, { + visible: true, + position: displayPoint, + rotation: orientationOf(this.intersection.surfaceNormal), + size: { + x: laserSize, + y: laserSize + } + }); + + } else { + this.hitFail(); + } + } else { + this.hitFail(); + } + }; + + this.hitFail = function() { + this.canPaint = false; + Overlays.editOverlay(this.laserPointer, { - visible: true, - position: displayPoint, - rotation: orientationOf(this.intersection.surfaceNormal), - size: { - x: laserSize, - y: laserSize - } + visible: false }); - } else { - this.hitFail(); - } - } else { - this.hitFail(); } - }; - this.hitFail = function() { - this.canPaint = false; - - Overlays.editOverlay(this.laserPointer, { - visible: false - }); - - } - - this.cleanup = function() { - Overlays.deleteOverlay(this.laserPointer); - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } - - this.cycleColorDown = function() { - this.strokeColor.h -= HUE_INCREMENT; - if (this.strokeColor.h < 0) { - this.strokeColor = 1; + this.cleanup = function() { + Overlays.deleteOverlay(this.laserPointer); + this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); } - Overlays.editOverlay(this.laserPointer, { - color: hslToRgb(this.strokeColor) - }); - } - this.cycleColorUp = function() { - this.strokeColor.h += HUE_INCREMENT; - if (this.strokeColor.h > 1) { - this.strokeColor.h = 0; + this.cycleColorDown = function() { + this.strokeColor.h -= HUE_INCREMENT; + if (this.strokeColor.h < 0) { + this.strokeColor = 1; + } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); + } + + this.cycleColorUp = function() { + this.strokeColor.h += HUE_INCREMENT; + if (this.strokeColor.h > 1) { + this.strokeColor.h = 0; + } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } - Overlays.editOverlay(this.laserPointer, { - color: hslToRgb(this.strokeColor) - }); - } } var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); Controller.actionEvent.connect(function(action, state) { - if (state === 0) { - return; - } - if (action === RIGHT_4_ACTION) { - rightController.cycleColorUp(); - } else if (action === RIGHT_2_ACTION) { - rightController.cycleColorDown(); - } - if (action === LEFT_4_ACTION) { - leftController.cycleColorUp(); - } else if (action === LEFT_2_ACTION) { - leftController.cycleColorDown(); - } + if (state === 0) { + return; + } + if (action === RIGHT_4_ACTION) { + rightController.cycleColorUp(); + } else if (action === RIGHT_2_ACTION) { + rightController.cycleColorDown(); + } + if (action === LEFT_4_ACTION) { + leftController.cycleColorUp(); + } else if (action === LEFT_2_ACTION) { + leftController.cycleColorDown(); + } }); function update() { - rightController.update(); - leftController.update(); + rightController.update(); + leftController.update(); } function cleanup() { - rightController.cleanup(); - leftController.cleanup(); + rightController.cleanup(); + leftController.cleanup(); } Script.scriptEnding.connect(cleanup); Script.update.connect(update); - - -function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; - - var theta = 0.0; - - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); -} - -/** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * @param Number h The hue - * @param Number s The saturation - * @param Number l The lightness - * @return Array The RGB representation - */ -function hslToRgb(hsl, hueOffset) { - var r, g, b; - if (hsl.s == 0) { - r = g = b = hsl.l; // achromatic - } else { - var hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - } - - var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; - var p = 2 * hsl.l - q; - r = hue2rgb(p, q, hsl.h + 1 / 3); - g = hue2rgb(p, q, hsl.h); - b = hue2rgb(p, q, hsl.h - 1 / 3); - } - - return { - red: Math.round(r * 255), - green: Math.round(g * 255), - blue: Math.round(b * 255) - }; -} - -function map(value, min1, max1, min2, max2) { - return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); -} \ No newline at end of file diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index f6f635c73a..fa0f36cbb1 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,3 +179,69 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +hslToRgb = function(hsl, hueOffset) { + var r, g, b; + if (hsl.s == 0) { + r = g = b = hsl.l; // achromatic + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; + var p = 2 * hsl.l - q; + r = hue2rgb(p, q, hsl.h + 1 / 3); + g = hue2rgb(p, q, hsl.h); + b = hue2rgb(p, q, hsl.h - 1 / 3); + } + + return { + red: Math.round(r * 255), + green: Math.round(g * 255), + blue: Math.round(b * 255) + }; +} + +map = function(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); +} + +orientationOf = function(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} + From 8e2c1a6b170a518923238a9456bc78952644e5bd Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 15:22:45 -0700 Subject: [PATCH 375/418] Add ping pong ball gun, add basketball hoop, reduce gate gravity, lint code --- examples/toys/masterResetEntity.js | 190 ++++++++++++++--------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 4750b5657b..501e59fc5b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -8,7 +8,7 @@ /*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ //per script -/*global deleteAllToys, createAllToys, createGates, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ +/*global deleteAllToys, createAllToys, createGates, createPingPongBallGun, createFire, createPottedPlant, createCombinedArmChair, createBasketballHoop, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); @@ -71,13 +71,11 @@ function createAllToys() { // //Handles toggling of all sconce lights createLightSwitches(); - - createCombinedArmChair({ x: 549.29, y: 495.05, z: 508.22 - }) + }); createPottedPlant({ x: 554.26, @@ -85,6 +83,9 @@ function createAllToys() { z: 504.53 }); + createPingPongBallGun(); + + createBasketballHoop(); createGates(); @@ -106,7 +107,7 @@ function deleteAllToys() { function createFire() { - myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); + var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); var animationSettings = JSON.stringify({ fps: 30, @@ -143,13 +144,13 @@ function createFire() { green: 99, blue: 32 }, - radiusSpread: .01, - radiusStart: .02, + radiusSpread: 0.01, + radiusStart: 0.02, radiusEnd: 0.001, - particleRadius: .05, + particleRadius: 0.05, radiusFinish: 0.0, emitOrientation: myOrientation, - emitSpeed: .3, + emitSpeed: 0.3, speedSpread: 0.1, alphaStart: 0.05, alpha: 0.1, @@ -157,7 +158,7 @@ function createFire() { emitDimensions: { x: 1, y: 1, - z: .1 + z: 0.1 }, polarFinish: 0.1, emitAcceleration: { @@ -383,7 +384,7 @@ function createGates() { collisionsWillMove: true, gravity: { x: 0, - y: -100, + y: -50, z: 0 }, linearDamping: 1, @@ -437,6 +438,86 @@ function createGates() { }); } +function createPingPongBallGun() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + var scriptURL = Script.resolvePath('ping_pong_gun/pingPongGun.js'); + + var position = { + x: 548.6, + y: 495.4, + z: 503.39 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); + + var pingPongGun = Entities.addEntity({ + type: "Model", + modelURL: MODEL_URL, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL, + position: position, + rotation: rotation, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 0.67, + y: 0.14, + z: 0.09 + }, + collisionsWillMove: true, + }); + + setEntityCustomData(resetKey, pingPongGun, { + resetMe: true + }); + + +} + +function createBasketballHoop() { + var position = { + x: 539.23, + y: 496.13, + z: 475.89 + }; + var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); + + var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; + var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; + + var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: position, + rotation: rotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL + }); + + setEntityCustomData(resetKey, hoop, { + resetMe: true + }); + + setEntityCustomData(GRABBABLE_DATA_KEY, hoop, { + grabbable: false + }); +} + function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; @@ -579,12 +660,9 @@ function createSprayCan(position) { } -//createPottedPlant,createArmChair,createPillow function createPottedPlant(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var entity = Entities.addEntity({ type: "Model", name: "Potted Plant", @@ -618,12 +696,12 @@ function createPottedPlant(position) { setEntityCustomData(GRABBABLE_DATA_KEY, entity, { grabbable: false }); -}; +} function createCombinedArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); @@ -661,85 +739,7 @@ function createCombinedArmChair(position) { setEntityCustomData(GRABBABLE_DATA_KEY, entity, { grabbable: false }); -}; - -function createArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 1.26, - y: 1.56, - z: 1.35 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -0.5, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.3 - }); - - setEntityCustomData(resetKey, entity, { - resetMe: true - }); -}; - -function createPillow(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; - var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair Pillow", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 0.4, - y: 0.4, - z: 0.4 - }, - collisionsWillMove: true, - ignoreForCollisions: false, - gravity: { - x: 0, - y: -10.1, - z: 0 - }, - restitution: 0, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - linearDamping: 1 - }); - - setEntityCustomData(resetKey, entity, { - resetMe: true - }); -}; +} function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; From 25e25726d59d09c719234ea7694f376336fcd856 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:43:25 -0700 Subject: [PATCH 376/418] only lights --- examples/toys/masterResetEntity.js | 116 ++++++++++++++++------------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 4750b5657b..0382e569bb 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -20,75 +20,89 @@ var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted -deleteAllToys(); +// deleteAllToys(); +deleteLights(); createAllToys(); function createAllToys() { - createBlocks({ - x: 548.3, - y: 495.55, - z: 504.4 - }); + // createBlocks({ + // x: 548.3, + // y: 495.55, + // z: 504.4 + // }); - createSprayCan({ - x: 549.7, - y: 495.6, - z: 503.91 - }); + // createSprayCan({ + // x: 549.7, + // y: 495.6, + // z: 503.91 + // }); - createBasketBall({ - x: 547.73, - y: 495.5, - z: 505.47 - }); + // createBasketBall({ + // x: 547.73, + // y: 495.5, + // z: 505.47 + // }); - createDoll({ - x: 546.67, - y: 495.41, - z: 505.09 - }); + // createDoll({ + // x: 546.67, + // y: 495.41, + // z: 505.09 + // }); - createWand({ - x: 546.71, - y: 495.55, - z: 506.15 - }); + // createWand({ + // x: 546.71, + // y: 495.55, + // z: 506.15 + // }); - createDice(); + // createDice(); - createFlashlight({ - x: 545.72, - y: 495.41, - z: 505.78 - }); + // createFlashlight({ + // x: 545.72, + // y: 495.41, + // z: 505.78 + // }); - createCat({ - x: 551.09, - y: 494.98, - z: 503.49 - }); + // createCat({ + // x: 551.09, + // y: 494.98, + // z: 503.49 + // }); + // createCombinedArmChair({ + // x: 549.29, + // y: 495.05, + // z: 508.22 + // }) + + // createPottedPlant({ + // x: 554.26, + // y: 495.23, + // z: 504.53 + // }); + + + // createGates(); + + // createFire(); // //Handles toggling of all sconce lights createLightSwitches(); - createCombinedArmChair({ - x: 549.29, - y: 495.05, - z: 508.22 - }) +} - createPottedPlant({ - x: 554.26, - y: 495.23, - z: 504.53 +function deleteLights() { + var entities = Entities.findEntities(MyAvatar.position, 100); + + entities.forEach(function(entity) { + //params: customKey, id, defaultValue + var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + var lightType = getEntityCustomData(resetKey, entity, {}).lightType; + if (shouldReset === true && (lightType === "Sconce Light Garage" || lightType === "Sconce Light Hall")) { + Entities.deleteEntity(entity); + } }); - - - createGates(); - - createFire(); } function deleteAllToys() { From e56d2d9b434622a63e1485ea5e16b945202d2ba6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 1 Oct 2015 15:48:37 -0700 Subject: [PATCH 377/418] Add asserts --- libraries/shared/src/Interpolate.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/shared/src/Interpolate.cpp b/libraries/shared/src/Interpolate.cpp index bc18c087ad..7acc0c8cbd 100644 --- a/libraries/shared/src/Interpolate.cpp +++ b/libraries/shared/src/Interpolate.cpp @@ -11,14 +11,18 @@ #include "Interpolate.h" +#include #include float Interpolate::bezierInterpolate(float y1, float y2, float y3, float u) { // https://en.wikipedia.org/wiki/Bezier_curve + assert(0.0f <= u && u <= 1.0f); return (1.0f - u) * (1.0f - u) * y1 + 2.0f * (1.0f - u) * u * y2 + u * u * y3; } float Interpolate::interpolate3Points(float y1, float y2, float y3, float u) { + assert(0.0f <= u && u <= 1.0f); + if (u <= 0.5f && y1 == y2 || u >= 0.5f && y2 == y3) { // Flat line. return y2; From cdb249c6ff1add3932d1759429c3f0de8efd8363 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:53:28 -0700 Subject: [PATCH 378/418] original master script --- examples/toys/masterResetEntity.js | 100 ++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 0382e569bb..ef7990b942 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -20,71 +20,71 @@ var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted -// deleteAllToys(); -deleteLights(); +deleteAllToys(); +// deleteLights(); createAllToys(); function createAllToys() { - // createBlocks({ - // x: 548.3, - // y: 495.55, - // z: 504.4 - // }); + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); - // createSprayCan({ - // x: 549.7, - // y: 495.6, - // z: 503.91 - // }); + createSprayCan({ + x: 549.7, + y: 495.6, + z: 503.91 + }); - // createBasketBall({ - // x: 547.73, - // y: 495.5, - // z: 505.47 - // }); + createBasketBall({ + x: 547.73, + y: 495.5, + z: 505.47 + }); - // createDoll({ - // x: 546.67, - // y: 495.41, - // z: 505.09 - // }); + createDoll({ + x: 546.67, + y: 495.41, + z: 505.09 + }); - // createWand({ - // x: 546.71, - // y: 495.55, - // z: 506.15 - // }); + createWand({ + x: 546.71, + y: 495.55, + z: 506.15 + }); - // createDice(); + createDice(); - // createFlashlight({ - // x: 545.72, - // y: 495.41, - // z: 505.78 - // }); + createFlashlight({ + x: 545.72, + y: 495.41, + z: 505.78 + }); - // createCat({ - // x: 551.09, - // y: 494.98, - // z: 503.49 - // }); + createCat({ + x: 551.09, + y: 494.98, + z: 503.49 + }); - // createCombinedArmChair({ - // x: 549.29, - // y: 495.05, - // z: 508.22 - // }) + createCombinedArmChair({ + x: 549.29, + y: 495.05, + z: 508.22 + }) - // createPottedPlant({ - // x: 554.26, - // y: 495.23, - // z: 504.53 - // }); + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); - // createGates(); + createGates(); - // createFire(); + createFire(); // //Handles toggling of all sconce lights createLightSwitches(); From 0fb51a67778bc6bfe902aabe2bd2162127bf9b12 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:56:16 -0700 Subject: [PATCH 379/418] got rid of unneeded light test code --- examples/toys/masterResetEntity.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index ef7990b942..966acc19b2 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -21,7 +21,6 @@ var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); -// deleteLights(); createAllToys(); function createAllToys() { @@ -92,19 +91,6 @@ function createAllToys() { } -function deleteLights() { - var entities = Entities.findEntities(MyAvatar.position, 100); - - entities.forEach(function(entity) { - //params: customKey, id, defaultValue - var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - var lightType = getEntityCustomData(resetKey, entity, {}).lightType; - if (shouldReset === true && (lightType === "Sconce Light Garage" || lightType === "Sconce Light Hall")) { - Entities.deleteEntity(entity); - } - }); -} - function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); From 407b6b8158b34dc1a729cb15e2f2bc90f78ae5f3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 16:10:29 -0700 Subject: [PATCH 380/418] Fixed bug in spray paint where sometimes would not spray --- examples/toys/sprayPaintCan.js | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 4716885ac3..0de95f5d93 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -101,6 +101,7 @@ this.disableStream = function() { Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.spraying = false; this.sprayInjector.stop(); } @@ -145,35 +146,3 @@ }); } }); - - - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} - -function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; - - var theta = 0.0; - - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); -} \ No newline at end of file From fe5ea471a1bd6faefe6ff90c5f80388ae89a10b7 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 1 Oct 2015 16:10:33 -0700 Subject: [PATCH 381/418] AnimClip: read in translations from fbx file and pre-process them Do the following things to the translations 1. scale by the model offset, this should move the translations into the correct units (meters). 2. compute the ratio between the bone length in the animation and the skeleton. 3. subtract the anim translation from the first translation frame in the animation effectively turning it into a bind pose delta translation. 4. apply bone length ratio to the resulting delta. 5. set the final translation to be the skeleton rel bind pose + this scaled delta translation --- libraries/animation/src/AnimClip.cpp | 47 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index f33c958fa8..c432b3b9ac 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -135,29 +135,46 @@ void AnimClip::copyFromNetworkAnim() { const int frameCount = geom.animationFrames.size(); const int skeletonJointCount = _skeleton->getNumJoints(); _anim.resize(frameCount); - for (int i = 0; i < frameCount; i++) { + + const glm::vec3 offsetScale = extractScale(geom.offset); + + for (int frame = 0; frame < frameCount; frame++) { // init all joints in animation to bind pose - _anim[i].reserve(skeletonJointCount); - for (int j = 0; j < skeletonJointCount; j++) { - _anim[i].push_back(_skeleton->getRelativeBindPose(j)); + // this will give us a resonable result for bones in the skeleton but not in the animation. + _anim[frame].reserve(skeletonJointCount); + for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) { + _anim[frame].push_back(_skeleton->getRelativeBindPose(skeletonJoint)); } - // init over all joint animations - for (int j = 0; j < animJointCount; j++) { - int k = jointMap[j]; - if (k >= 0 && k < skeletonJointCount) { - _anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j]; + for (int animJoint = 0; animJoint < animJointCount; animJoint++) { - // TODO -- why does applying all the joint translations make a mutant? - if (animJoints[j].parentIndex == -1) { - _anim[i][k].trans = geom.animationFrames[i].translations[j] * extractScale(geom.offset); - } else { - _anim[i][k].trans = _skeleton->getRelativeBindPose(k).trans; - } + int skeletonJoint = jointMap[animJoint]; + + // skip joints that are in the animation but not in the skeleton. + if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { + + const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint] * offsetScale; + const AnimPose& relBindPose = _skeleton->getRelativeBindPose(skeletonJoint); + + // used to adjust translation offsets, so large translation animatons on the reference skeleton + // will be adjusted when played on a skeleton with short limbs. + float limbLengthScale = fabs(glm::length(fbxZeroTrans)) <= 0.0001f ? 1.0f : (glm::length(relBindPose.trans) / glm::length(fbxZeroTrans)); + + AnimPose& pose = _anim[frame][skeletonJoint]; + const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame]; + + // rotation in fbxAnimationFrame is a delta from a reference skeleton bind pose. + pose.rot = relBindPose.rot * fbxAnimFrame.rotations[animJoint]; + + // translation in fbxAnimationFrame is not a delta. + // convert it into a delta by subtracting from the first frame. + const glm::vec3& fbxTrans = fbxAnimFrame.translations[animJoint] * offsetScale; + pose.trans = relBindPose.trans + limbLengthScale * (fbxTrans - fbxZeroTrans); } } } + _poses.resize(skeletonJointCount); } From b352ab473632a4c1bbecb73cc28ab8b233866772 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:04:37 -0700 Subject: [PATCH 382/418] Update lightSwitchGarage.js fix header and spacing issues --- examples/toys/lightSwitchGarage.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 5f302ff47e..19d33117df 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -1,11 +1,10 @@ // -// detectGrabExample.js +// lightSwitchGarage.js.js // examples/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -15,7 +14,6 @@ var _this; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) LightSwitchGarage = function() { @@ -78,7 +76,6 @@ createLights: function() { - var sconceLight3 = Entities.addEntity({ type: "Light", position: { @@ -113,7 +110,6 @@ y: 496.24026489257812, z: 507.90237426757812 }, - name: "Sconce 4 Light", dimensions: { x: 2.545, @@ -159,12 +155,9 @@ lightType: "Sconce Light Garage" }); - - setEntityCustomData(this.lightStateKey, this.entityID, { on: true }); - }, flipLights: function() { @@ -185,9 +178,6 @@ }, - - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { this.entityID = entityID; @@ -209,4 +199,4 @@ // entity scripts always need to return a newly constructed object of our type return new LightSwitchGarage(); -}) \ No newline at end of file +}) From 9098585e2fa975abef2a5694713bb9eaee3c740d Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:14:08 -0700 Subject: [PATCH 383/418] Update cat.js remove a lot of unused code and add flag for whether cat is already meowing so that it doesn't start another one until its done. unfortunately i dont know how to read the audio isplaying state so we have to use a lame timeout --- examples/toys/cat.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index a71cec95c2..156765ed00 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -1,12 +1,11 @@ // -// doll.js +// cat.js // examples/toybox/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This entity script breathes movement and sound- one might even say life- into a doll. -// + // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -15,20 +14,23 @@ var _this; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - this.distanceThreshold = 1; - this.canMeow = true; - this.meowBreakTime = 3000; }; Cat.prototype = { - + isMeowing:false, startTouch: function() { - this.meow(); + var _ t=this; + if(this.isMeowing!==true){ + this.meow(); + this.isMeowing=true; + Script.setTimeout(function(){ + _t.isMeowing=false; + },2000) + } + }, meow: function() { @@ -38,14 +40,10 @@ volume: .1 }); }, - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; - Script.update.connect(this.update); }, unload: function() { @@ -55,4 +53,4 @@ // entity scripts always need to return a newly constructed object of our type return new Cat(); -}); \ No newline at end of file +}); From cfb9728fdb8d4478d0cc2d9e3be4b8dd394bc697 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:17:35 -0700 Subject: [PATCH 384/418] Update doll.js remove some unused code --- examples/toys/doll/doll.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index eeb4f8ee8a..79e8a28fb5 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -56,12 +56,11 @@ }, continueNearGrab: function() { - var props = Entities.getEntityProperties(this.entityID, ["position", "animationFrameIndex"]); + var props = Entities.getEntityProperties(this.entityID, ["position"]); var audioOptions = { position: props.position }; this.audioInjector.options = audioOptions; - }, releaseGrab: function() { @@ -84,12 +83,9 @@ }, preload: function(entityID) { - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID this.entityID = entityID; }, }; // entity scripts always need to return a newly constructed object of our type return new Doll(); -}); \ No newline at end of file +}); From 6523a057a866418d77dfead1efde6175bc56f442 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:18:27 -0700 Subject: [PATCH 385/418] Update lightSwitchHall.js fix header file --- examples/toys/lightSwitchHall.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 4dd1a867de..e1093311f9 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -1,11 +1,10 @@ // -// detectGrabExample.js +// lightSwitchHall.js // examples/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -25,7 +24,6 @@ this.resetKey = "resetMe"; this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - }; LightSwitchHall.prototype = { @@ -178,4 +176,4 @@ // entity scripts always need to return a newly constructed object of our type return new LightSwitchHall(); -}) \ No newline at end of file +}) From 54a51e6b8b11a210bbf2939e774d5ceba63fac4e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:19:36 -0700 Subject: [PATCH 386/418] Update and rename masterResetEntity.js to masterReset.js remove reference to 'entities' in the file name since this script does more than that. also update the header file. --- examples/toys/{masterResetEntity.js => masterReset.js} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename examples/toys/{masterResetEntity.js => masterReset.js} (99%) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterReset.js similarity index 99% rename from examples/toys/masterResetEntity.js rename to examples/toys/masterReset.js index f9471611be..8137f27f70 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterReset.js @@ -1,4 +1,4 @@ -// +// masterReset.js // Created by Eric Levin on 9/23/2015 // Copyright 2015 High Fidelity, Inc. // @@ -842,4 +842,4 @@ function randFloat(low, high) { function randInt(low, high) { return Math.floor(randFloat(low, high)); -} \ No newline at end of file +} From 3565d96ffb19b225798e161cc492e85d860c3240 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:21:15 -0700 Subject: [PATCH 387/418] Update sprayPaintCan.js add a header, cleanup --- examples/toys/sprayPaintCan.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 0de95f5d93..5c524a38bc 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -1,3 +1,14 @@ +// +// sprayPaintCan.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + (function() { // Script.include("../libraries/utils.js"); //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge @@ -13,7 +24,7 @@ x: 0, y: 0, z: 0 - } + }; // if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray var DISABLE_SPRAY_THRESHOLD = 0.5; @@ -129,14 +140,12 @@ } - this.preload = function(entityId) { this.spraying = false; this.entityId = entityId; this.resetKey = "resetMe"; } - this.unload = function() { if (this.paintStream) { Entities.deleteEntity(this.paintStream); From 6cc2df90524511a57e491f9c90b0850a914e5c84 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:34:22 -0700 Subject: [PATCH 388/418] Update cat.js hook into isPlaying for sounds --- examples/toys/cat.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 156765ed00..34dea1fb80 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -21,29 +21,36 @@ Cat.prototype = { isMeowing:false, + this.injector:null, startTouch: function() { var _ t=this; if(this.isMeowing!==true){ this.meow(); this.isMeowing=true; - Script.setTimeout(function(){ - _t.isMeowing=false; - },2000) } }, - + + update:function(){ + if(this.injector!==null){ + this.isMeowing = this.injector.isPlaying; + } + if(this.isMeowing===false){ + this.injector=null + } + } + meow: function() { - - Audio.playSound(this.meowSound, { + this.injector = Audio.playSound(this.meowSound, { position: this.position, - volume: .1 + volume: 0.1 }); }, preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; + Script.update.connect(this.update); }, unload: function() { From f200fcdfa2704a9fc0edcfc1e5078ed92e284dc4 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:35:34 -0700 Subject: [PATCH 389/418] Update cat.js --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 34dea1fb80..bde0a5a2c4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -21,7 +21,7 @@ Cat.prototype = { isMeowing:false, - this.injector:null, + injector:null, startTouch: function() { var _ t=this; if(this.isMeowing!==true){ From 59c1c7ee6a6502dc14340a598ebae718d4a0e607 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:40:12 -0700 Subject: [PATCH 390/418] Update masterReset.js remove file versioning --- examples/toys/masterReset.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/toys/masterReset.js b/examples/toys/masterReset.js index 8137f27f70..029f7f1ba6 100644 --- a/examples/toys/masterReset.js +++ b/examples/toys/masterReset.js @@ -188,7 +188,7 @@ function createFire() { function createCat(position) { - var scriptURL = Script.resolvePath("cat.js?v1"); + var scriptURL = Script.resolvePath("cat.js"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; var animationSettings = JSON.stringify({ @@ -256,8 +256,8 @@ function createFlashlight(position) { } function createLightSwitches() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; - var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; + var scriptURL = Script.resolvePath("lightSwitchHall.js"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -286,7 +286,7 @@ function createLightSwitches() { resetMe: true }); - scriptURL = Script.resolvePath("lightSwitchGarage.js?v1"); + scriptURL = Script.resolvePath("lightSwitchGarage.js"); var lightSwitchGarage = Entities.addEntity({ type: "Model", @@ -597,7 +597,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js?v2"); + var scriptURL = Script.resolvePath("doll/doll.js"); var naturalDimensions = { x: 1.63, @@ -632,7 +632,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("sprayPaintCan.js?v1" + Math.random()); + var scriptURL = Script.resolvePath("sprayPaintCan.js") ; var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 55d20e9d4cd30b9f10a8405ad1e710f90207241e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:41:24 -0700 Subject: [PATCH 391/418] Update cat.js --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index bde0a5a2c4..44991dd9bd 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -23,7 +23,7 @@ isMeowing:false, injector:null, startTouch: function() { - var _ t=this; + var _t=this; if(this.isMeowing!==true){ this.meow(); this.isMeowing=true; From 3490e08521360bde1d0f0266f64ddacbab48a410 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 18:42:09 -0700 Subject: [PATCH 392/418] Little improvments on the performance side to get the Stencil pass and the masking of the background under reasonable performances --- .../gpu/src/gpu/DrawUnitQuadTexcoord.slv | 28 +++++++++++++ libraries/gpu/src/gpu/GLBackend.cpp | 39 ++++++++++++------- libraries/gpu/src/gpu/GLBackendState.cpp | 23 +++++++---- libraries/gpu/src/gpu/GLBackendTransform.cpp | 30 ++++++++------ libraries/gpu/src/gpu/StandardShaderLib.cpp | 8 ++++ libraries/gpu/src/gpu/StandardShaderLib.h | 4 ++ .../render-utils/src/RenderDeferredTask.cpp | 21 ++++------ 7 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv diff --git a/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv new file mode 100644 index 0000000000..60ab0bd7dd --- /dev/null +++ b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the unit quad [-1,-1 -> 1,1] amd pass along the unit texcoords [0, 0 -> 1, 1]. Not transform used. +// Simply draw a Triangle_strip of 2 triangles, no input buffers or index buffer needed +// +// Created by Sam Gateau on 6/22/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +out vec2 varTexCoord0; + +void main(void) { + const vec4 UNIT_QUAD[4] = vec4[4]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0) + ); + vec4 pos = UNIT_QUAD[gl_VertexID]; + + varTexCoord0 = (pos.xy + 1) * 0.5; + + gl_Position = pos; +} diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 250fc4aaac..b1e63a18bd 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -132,20 +132,26 @@ void GLBackend::renderPassTransfer(Batch& batch) { const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data(); - - for (auto& cached : batch._buffers._items) { - if (cached._data) { - syncGPUObject(*cached._data); + + { // Sync all the buffers + PROFILE_RANGE("syncGPUBuffer"); + + for (auto& cached : batch._buffers._items) { + if (cached._data) { + syncGPUObject(*cached._data); + } } } - // Reset the transform buffers - _transform._cameras.resize(0); - _transform._cameraOffsets.clear(); - _transform._objects.resize(0); - _transform._objectOffsets.clear(); - for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { - switch (*command) { + { // Sync all the buffers + PROFILE_RANGE("syncCPUTransform"); + _transform._cameras.resize(0); + _transform._cameraOffsets.clear(); + _transform._objects.resize(0); + _transform._objectOffsets.clear(); + + for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { + switch (*command) { case Batch::COMMAND_draw: case Batch::COMMAND_drawIndexed: case Batch::COMMAND_drawInstanced: @@ -164,11 +170,16 @@ void GLBackend::renderPassTransfer(Batch& batch) { default: break; + } + command++; + offset++; } - command++; - offset++; } - _transform.transfer(); + + { // Sync the transform buffers + PROFILE_RANGE("syncGPUTransform"); + _transform.transfer(); + } } void GLBackend::renderPassDraw(Batch& batch) { diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index feba6e6853..895d0a0027 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -642,8 +642,13 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S if (activation.isEnabled()) { glEnable(GL_STENCIL_TEST); - glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); - glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + + if (activation.getWriteMaskFront() != activation.getWriteMaskBack()) { + glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); + glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + } else { + glStencilMask(activation.getWriteMaskFront()); + } static GLenum STENCIL_OPS[] = { GL_KEEP, @@ -655,12 +660,16 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - - glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + if (frontTest != backTest) { + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { + glStencilOp(STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFunc(GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + } } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 4a55155a86..5e16421c6a 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -130,19 +130,27 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo void GLBackend::TransformStageState::transfer() const { static QByteArray bufferData; - glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); - bufferData.resize(_cameraUboSize * _cameras.size()); - for (size_t i = 0; i < _cameras.size(); ++i) { - memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + if (!_cameras.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); + bufferData.resize(_cameraUboSize * _cameras.size()); + for (size_t i = 0; i < _cameras.size(); ++i) { + memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - bufferData.resize(_objectUboSize * _objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) { - memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + + if (!_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); + bufferData.resize(_objectUboSize * _objects.size()); + for (size_t i = 0; i < _objects.size(); ++i) { + memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + } + + if (!_cameras.empty() || !_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, 0); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 3f27a7fc35..864bff08c9 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -12,6 +12,7 @@ // #include "StandardShaderLib.h" +#include "DrawUnitQuadTexcoord_vert.h" #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" @@ -21,6 +22,7 @@ using namespace gpu; +ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; @@ -55,6 +57,12 @@ ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) { } +ShaderPointer StandardShaderLib::getDrawUnitQuadTexcoordVS() { + if (!_drawUnitQuadTexcoordVS) { + _drawUnitQuadTexcoordVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(DrawUnitQuadTexcoord_vert))); + } + return _drawUnitQuadTexcoordVS; +} ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() { if (!_drawTransformUnitQuadVS) { diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 2d9c168473..12ea9045c2 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -23,6 +23,9 @@ namespace gpu { class StandardShaderLib { public: + // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and the unit texcoord = [(0,0),(1,1)]. + static ShaderPointer getDrawUnitQuadTexcoordVS(); + // Shader draw the unit quad objectPos = ([(-1,-1),(1,1)]) and transform it by the full model transform stack (Model, View, Proj). // A texcoord attribute is also generated texcoord = [(0,0),(1,1)] static ShaderPointer getDrawTransformUnitQuadVS(); @@ -44,6 +47,7 @@ public: protected: + static ShaderPointer _drawUnitQuadTexcoordVS; static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 504070963d..983c2d44ba 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -37,15 +37,19 @@ void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderCon RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + auto primaryFboStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); batch.enableStereo(false); - batch.setFramebuffer(nullptr); - batch.setFramebuffer(primaryFbo); - batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.setFramebuffer(primaryFboStencil); + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_STENCIL, + vec4(vec3(0), 1), 1.0, 0.0, true); + + batch.setFramebuffer(primaryFbo); batch.clearFramebuffer( gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, @@ -68,7 +72,6 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - // _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", @@ -302,7 +305,7 @@ gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); @@ -329,7 +332,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren args->_batch = &batch; auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); - auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); batch.enableStereo(false); @@ -337,11 +339,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.setFramebuffer(primaryFboColorDepthStencil); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.clearStencilFramebuffer(0, true); - - - Transform modelMat; - batch.setModelTransform(modelMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -349,8 +346,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, nullptr); - batch.setFramebuffer(primaryFboFull); - }); args->_batch = nullptr; } From d0e079ee9dd48e82c74e2d36b86701cb50377cf5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:46:32 -0700 Subject: [PATCH 393/418] Update cat.js add globals, lint the code --- examples/toys/cat.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 44991dd9bd..537e0c21b4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -8,45 +8,42 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// +/*global Cat, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ + (function() { - var _this; - Cat = function() { - _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); }; Cat.prototype = { - isMeowing:false, - injector:null, + isMeowing: false, + injector: null, startTouch: function() { - var _t=this; - if(this.isMeowing!==true){ + if (this.isMeowing !== true) { this.meow(); - this.isMeowing=true; + this.isMeowing = true; } }, - - update:function(){ - if(this.injector!==null){ - this.isMeowing = this.injector.isPlaying; + + update: function() { + if (this.injector !== null) { + this.isMeowing = this.injector.isPlaying; } - if(this.isMeowing===false){ - this.injector=null + if (this.isMeowing === false) { + this.injector = null; } - } - + }, + meow: function() { this.injector = Audio.playSound(this.meowSound, { position: this.position, volume: 0.1 }); }, - + preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; From 0ce6a305bdb200fa85949eda66f4e918fd9642f6 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:52:08 -0700 Subject: [PATCH 394/418] Update cat.js --- examples/toys/cat.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 537e0c21b4..63a8a351d4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -13,7 +13,9 @@ (function() { +var _this; Cat = function() { + _this=this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); }; @@ -29,11 +31,11 @@ }, update: function() { - if (this.injector !== null) { - this.isMeowing = this.injector.isPlaying; + if (_this.injector !== null) { + _this.isMeowing = this.injector.isPlaying; } - if (this.isMeowing === false) { - this.injector = null; + if (_this.isMeowing === false) { + _this.injector = null; } }, From a3c91b12b9c8d1fa7cb83739adc95cd482279b78 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:56:38 -0700 Subject: [PATCH 395/418] Update cat.js --- examples/toys/cat.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 63a8a351d4..beca627539 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -33,10 +33,11 @@ var _this; update: function() { if (_this.injector !== null) { _this.isMeowing = this.injector.isPlaying; + if (_this.isMeowing === false) { + _this.injector = null; + } } - if (_this.isMeowing === false) { - _this.injector = null; - } + }, meow: function() { From 4b1b53e18943ffce6276292ddd6ff941955d40b0 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 19:01:10 -0700 Subject: [PATCH 396/418] end of dat --- examples/particle_explorer/main.js | 74 ++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 71caf4cafb..b25d54ea8f 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -23,7 +23,7 @@ var Settings = function() { var AUTO_UPDATE = false; -var UPDATE_ALL_FREQUENCY = 1000; +var UPDATE_ALL_FREQUENCY = 100; var controllers = []; var colorControllers = []; @@ -153,16 +153,17 @@ function loadGUI() { gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - if(AUTO_UPDATE){ + if (AUTO_UPDATE) { setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); } + registerDOMElementsForListenerBlocking(); } function addIndividualKeys() { _.each(individualKeys, function(key) { - var controller = gui.add(settings, key); + var controller = gui.add(settings, key).listen(); //need to fix not being able to input values if constantly listening //.listen(); @@ -179,8 +180,7 @@ function addIndividualKeys() { function addFolders() { _.each(colorKeys, function(key) { - console.log('COLOR KEY IS' + key) - // createColorFolder(key); + // createColorFolder(key); createColorPicker(key); }); _.each(vec3Keys, function(key) { @@ -193,16 +193,13 @@ function addFolders() { } function createColorPicker(key) { - console.log('CREATE COLOR PICKER') var colorObject = settings[key]; var colorArray = convertColorObjectToArray(colorObject); settings[key] = colorArray; var controller = gui.addColor(settings, key); controller.onChange(function(value) { - console.log('COLOR VALUE' + value) var obj = {}; obj[key] = convertColorArrayToObject(value); - console.log('AFTER CONVERSION'); writeVec3ToInterface(obj); }); return; @@ -380,6 +377,7 @@ function writeVec3ToInterface(obj) { } window.onload = function() { + console.log('WINDOW ONLOAD'); if (typeof EventBridge !== 'undefined') { var stringifiedData = JSON.stringify({ @@ -392,7 +390,7 @@ window.onload = function() { listenForSettingsUpdates(); } else { - // console.log('No event bridge, probably not in interface.'); + console.log('No event bridge, probably not in interface.'); } }; @@ -459,9 +457,9 @@ function prepareSettingsForExport() { return; } - if(key.indexOf('color')>-1){ + if (key.indexOf('color') > -1) { var colorObject = convertColorArrayToObject(settings[key]); - settings[key]=colorObject + settings[key] = colorObject } exportSettings[key] = settings[key]; @@ -469,16 +467,56 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } -function removeListener(key){ - _.each(gui.__listening,function(controller,index){ - if(controller.property===key){ - console.log('CONTROLLER KEY MATCHES REMOVELISTENER KEY') - storedController = controller; - gui.__listening.splice(index,1); - } + +function removeListenerFromGUI(key) { + console.log('REMOVE ' + key ) + _.each(gui.__listening, function(controller, index) { + console.log('CONTROLLER AT REMOVE' + controller) + // if (controller.property === key) { + // storedController = controller; + // gui.__listening.splice(index, 1); + // } }); } +function addListenersBackToGUI(event) { + gui.__listening.push(storedController); + storedController = null; +} + +function registerDOMElementsForListenerBlocking() { + console.log('gui.__controllers length::: '+gui.__controllers.length) + + + + _.each(gui.__controllers, function(controller) { + var input = controller.domElement.childNodes[0]; + input.addEventListener('focus', function(event) { + console.log('INPUT ELEMENT GOT FOCUS!' + controller.property); + removeListenerFromGUI(controller.property); + }); + }) + + _.each(gui.__controllers, function(controller) { + var input = controller.domElement.childNodes[0]; + input.addEventListener('blur', function(event) { + console.log('INPUT ELEMENT GOT BLUR!' + controller.property); + addListenersBackToGUI(); + }); + }) + + // _.each(gui.__folders, function(folder) { + // _.each(folder.__controllers, function(controller) { + // var input = controller.__input; + // input.addEventListener('focus', function(event) { + // console.log('FOLDER ELEMENT GOT FOCUS!' + controller.property); + // }); + // }) + // }); +} + +// gui.__folders['Flow Field'].__controllers[0].__input + function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) From 690620d74d7889f831a078f18c26f81b7958d935 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 19:23:32 -0700 Subject: [PATCH 397/418] Cleaning code --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 7 ++----- libraries/model/src/model/Skybox.cpp | 2 +- libraries/render-utils/src/Environment.cpp | 2 -- libraries/render-utils/src/RenderDeferredTask.cpp | 1 - libraries/render-utils/src/drawOpaqueStencil.slf | 10 ++-------- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 044204934c..ee5e1d3bc6 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -360,11 +360,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (bytes && texture.isAutogenerateMips()) { glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - }/* else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - }*/ - + } + object->_target = GL_TEXTURE_2D; syncSampler(texture.getSampler(), texture.getType(), object); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e516fae583..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index acb149a3cc..b26d402fa3 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -62,8 +62,6 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); - // state->setDepthTest(false); - // state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 983c2d44ba..0f79dc8b8d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -314,7 +314,6 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index 883154c624..14feda21e9 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -13,18 +13,12 @@ // in vec2 varTexCoord0; -out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { - // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - - float depth = texture(depthTexture, varTexCoord0.xy).r; - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); - if (depth < 1.0) { - outFragColor = vec4(0.0, 1.0, 0.0, 1.0); - } else { + float depth = texture(depthTexture, varTexCoord0.xy).r; + if (depth >= 1.0) { discard; } } From e1e34b2ce5cbd20a972947977ca4e79a02e912da Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 20:17:04 -0700 Subject: [PATCH 398/418] Fix to allow arbitrary input/output buffers from caller. SIMD padding is no longer required. --- libraries/audio/src/AudioSRC.cpp | 78 ++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index e33d399213..99760fc42f 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -915,12 +915,10 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { __m128 scale = _mm_set1_ps(1/32768.0f); - numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute - assert(numFrames <= SRC_BLOCK); - if (_numChannels == 1) { - for (int i = 0; i < numFrames; i += 4) { + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128i a0 = _mm_loadl_epi64((__m128i*)&input[i]); // sign-extend @@ -930,9 +928,21 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int _mm_storeu_ps(&outputs[0][i], f0); } - } else if (_numChannels == 2) { - for (int i = 0; i < numFrames; i += 4) { + for (; i < numFrames; i++) { + __m128i a0 = _mm_insert_epi16(_mm_setzero_si128(), input[i], 0); + // sign-extend + a0 = _mm_srai_epi32(_mm_unpacklo_epi16(a0, a0), 16); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + + _mm_store_ss(&outputs[0][i], f0); + } + + } else if (_numChannels == 2) { + + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128i a0 = _mm_loadu_si128((__m128i*)&input[2*i]); __m128i a1 = a0; @@ -946,6 +956,20 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int _mm_storeu_ps(&outputs[0][i], f0); _mm_storeu_ps(&outputs[1][i], f1); } + for (; i < numFrames; i++) { + __m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]); + __m128i a1 = a0; + + // deinterleave and sign-extend + a0 = _mm_madd_epi16(a0, _mm_set1_epi32(0x00000001)); + a1 = _mm_madd_epi16(a1, _mm_set1_epi32(0x00010000)); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + __m128 f1 = _mm_mul_ps(_mm_cvtepi32_ps(a1), scale); + + _mm_store_ss(&outputs[0][i], f0); + _mm_store_ss(&outputs[1][i], f1); + } } } @@ -970,12 +994,10 @@ static inline __m128 dither4() { void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { __m128 scale = _mm_set1_ps(32768.0f); - numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute - assert(numFrames <= SRC_BLOCK); - if (_numChannels == 1) { - for (int i = 0; i < numFrames; i += 4) { + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); f0 = _mm_add_ps(f0, dither4()); @@ -986,9 +1008,22 @@ void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFram _mm_storel_epi64((__m128i*)&output[i], a0); } - } else if (_numChannels == 2) { - for (int i = 0; i < numFrames; i += 4) { + for (; i < numFrames; i++) { + __m128 f0 = _mm_mul_ps(_mm_load_ss(&inputs[0][i]), scale); + f0 = _mm_add_ps(f0, dither4()); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + a0 = _mm_packs_epi32(a0, a0); + + output[i] = (int16_t)_mm_extract_epi16(a0, 0); + } + + } else if (_numChannels == 2) { + + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); __m128 f1 = _mm_mul_ps(_mm_loadu_ps(&inputs[1][i]), scale); @@ -1004,9 +1039,26 @@ void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFram // interleave a0 = _mm_unpacklo_epi16(a0, a1); - _mm_storeu_si128((__m128i*)&output[2*i], a0); } + for (; i < numFrames; i++) { + __m128 f0 = _mm_mul_ps(_mm_load_ss(&inputs[0][i]), scale); + __m128 f1 = _mm_mul_ps(_mm_load_ss(&inputs[1][i]), scale); + + __m128 d0 = dither4(); + f0 = _mm_add_ps(f0, d0); + f1 = _mm_add_ps(f1, d0); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + __m128i a1 = _mm_cvtps_epi32(f1); + a0 = _mm_packs_epi32(a0, a0); + a1 = _mm_packs_epi32(a1, a1); + + // interleave + a0 = _mm_unpacklo_epi16(a0, a1); + *(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0); + } } } From 3555e90cf60360273f3fac159c05009b9528c223 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 20:32:48 -0700 Subject: [PATCH 399/418] Improved random generator for SIMD dither --- libraries/audio/src/AudioSRC.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index 99760fc42f..59fe29df36 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -975,11 +975,11 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int // fast TPDF dither in [-1.0f, 1.0f] static inline __m128 dither4() { - static __m128i rz = _mm_set_epi16(0, -12285, 8251, 22985, -4297, 14758, -19785, -26093); + static __m128i rz; - // update the parallel LCGs - rz = _mm_mullo_epi16(rz, _mm_set1_epi16(25173)); - rz = _mm_add_epi16(rz, _mm_set1_epi16(13849)); + // update the 8 different maximum-length LCGs + rz = _mm_mullo_epi16(rz, _mm_set_epi16(25173, -25511, -5975, -23279, 19445, -27591, 30185, -3495)); + rz = _mm_add_epi16(rz, _mm_set_epi16(13849, -32767, 105, -19675, -7701, -32679, -13225, 28013)); // promote to 32-bit __m128i r0 = _mm_unpacklo_epi16(rz, _mm_setzero_si128()); From 7c9d7ffefd4c8f065ac7d6a81dbeca56fe917b44 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 23:49:33 -0700 Subject: [PATCH 400/418] single sysytem particle explorer with one way bindings is feature complete --- examples/particle_explorer/index.html | 25 +- examples/particle_explorer/main.js | 256 ++++++++---------- .../particle_explorer/particleExplorer.js | 16 +- 3 files changed, 132 insertions(+), 165 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 06ffc0390b..4b9e2a9d36 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -6,34 +6,37 @@ // Copyright 2015 High Fidelity, Inc. // // Loads dat.gui, underscore, and the app -// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// Quickly edit the aesthetics of a particle system. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// +// --> - +